aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/xen-api/xenapi-datamodel.tex104
-rw-r--r--tools/libxen/include/xen_sr.h28
-rw-r--r--tools/libxen/src/xen_sr.c71
-rw-r--r--tools/python/xen/xend/XendAPI.py91
-rw-r--r--tools/python/xen/xend/XendLocalStorageRepo.py17
-rw-r--r--tools/python/xen/xend/XendNode.py39
-rw-r--r--tools/python/xen/xend/XendPBD.py79
-rw-r--r--tools/python/xen/xend/XendQCoWStorageRepo.py23
-rw-r--r--tools/python/xen/xend/XendStateStore.py2
-rw-r--r--tools/python/xen/xend/XendStorageRepository.py13
10 files changed, 241 insertions, 226 deletions
diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex
index 04fc5bccca..760f4bfc62 100644
--- a/docs/xen-api/xenapi-datamodel.tex
+++ b/docs/xen-api/xenapi-datamodel.tex
@@ -9190,51 +9190,35 @@ $\mathit{RO}_\mathit{run}$ & {\tt virtual\_allocation} & int & sum of virtual\_
$\mathit{RO}_\mathit{run}$ & {\tt physical\_utilisation} & int & physical space currently utilised on this storage repository (in bytes). Note that for sparse disk formats, physical\_utilisation may be less than virtual\_allocation \\
$\mathit{RO}_\mathit{ins}$ & {\tt physical\_size} & int & total physical size of the repository (in bytes) \\
$\mathit{RO}_\mathit{ins}$ & {\tt type} & string & type of the storage repository \\
-$\mathit{RO}_\mathit{ins}$ & {\tt location} & string & a string that uniquely determines the location of the storage repository; the format of this string depends on the repository's type \\
+$\mathit{RO}_\mathit{ins}$ & {\tt content\_type} & string & the type of the SR's content, if required (e.g. ISOs) \\
\hline
\end{longtable}
\subsection{RPCs associated with class: SR}
-\subsubsection{RPC name:~clone}
+\subsubsection{RPC name:~get\_supported\_types}
{\bf Overview:}
-Take an exact copy of the Storage Repository;
- the cloned storage repository has the same type as its parent
+Return a set of all the SR types supported by the system.
\noindent {\bf Signature:}
-\begin{verbatim} (SR ref) clone (session_id s, SR ref sr, string loc, string name)\end{verbatim}
-
+\begin{verbatim} (string Set) get_supported_types (session_id s)\end{verbatim}
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt SR ref } & sr & The Storage Repository to clone \\ \hline
-
-{\tt string } & loc & The location string that defines where the new storage repository will be located \\ \hline
-
-{\tt string } & name & The name of the new storage repository \\ \hline
-
-\end{tabular}
\vspace{0.3cm}
\noindent {\bf Return Type:}
{\tt
-SR ref
+string Set
}
-The ID of the newly created Storage Repository.
+the supported SR types
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
\subsubsection{RPC name:~get\_all}
{\bf Overview:}
-Return a list of all the Storage Repositories known to the system
+Return a list of all the SRs known to the system.
\noindent {\bf Signature:}
\begin{verbatim} ((SR ref) Set) get_all (session_id s)\end{verbatim}
@@ -9248,7 +9232,7 @@ Return a list of all the Storage Repositories known to the system
}
-A list of all the IDs of all the Storage Repositories
+references to all objects
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -9608,13 +9592,13 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~get\_location}
+\subsubsection{RPC name:~get\_content\_type}
{\bf Overview:}
-Get the location field of the given SR.
+Get the content\_type field of the given SR.
\noindent {\bf Signature:}
-\begin{verbatim} string get_location (session_id s, SR ref self)\end{verbatim}
+\begin{verbatim} string get_content_type (session_id s, SR ref self)\end{verbatim}
\noindent{\bf Arguments:}
@@ -9640,70 +9624,6 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~create}
-
-{\bf Overview:}
-Create a new SR instance, and return its handle.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (SR ref) create (session_id s, SR record args)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt SR record } & args & All constructor arguments \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-SR ref
-}
-
-
-reference to the newly created object
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~destroy}
-
-{\bf Overview:}
-Destroy the specified SR instance.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void destroy (session_id s, SR ref self)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt SR ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
\subsubsection{RPC name:~get\_by\_uuid}
{\bf Overview:}
@@ -11988,7 +11908,7 @@ Quals & Field & Type & Description \\
$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\
$\mathit{RO}_\mathit{ins}$ & {\tt host} & host ref & physical machine on which the pbd is available \\
$\mathit{RO}_\mathit{ins}$ & {\tt SR} & SR ref & the storage repository that the pbd realises \\
-$\mathit{RO}_\mathit{ins}$ & {\tt device\_config} & (string $\rightarrow$ string) Map & a config string that is provided to the host's SR-backend-driver \\
+$\mathit{RO}_\mathit{ins}$ & {\tt device\_config} & (string $\rightarrow$ string) Map & a config string to string map that is provided to the host's SR-backend-driver \\
$\mathit{RO}_\mathit{run}$ & {\tt currently\_attached} & bool & is the SR currently attached on this host? \\
\hline
\end{longtable}
diff --git a/tools/libxen/include/xen_sr.h b/tools/libxen/include/xen_sr.h
index e5e4299844..39a8dd6650 100644
--- a/tools/libxen/include/xen_sr.h
+++ b/tools/libxen/include/xen_sr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@
#include "xen_common.h"
#include "xen_pbd_decl.h"
#include "xen_sr_decl.h"
+#include "xen_string_set.h"
#include "xen_vdi_decl.h"
@@ -72,7 +73,7 @@ typedef struct xen_sr_record
int64_t physical_utilisation;
int64_t physical_size;
char *type;
- char *location;
+ char *content_type;
} xen_sr_record;
/**
@@ -169,20 +170,6 @@ xen_sr_get_by_uuid(xen_session *session, xen_sr *result, char *uuid);
/**
- * Create a new SR instance, and return its handle.
- */
-extern bool
-xen_sr_create(xen_session *session, xen_sr *result, xen_sr_record *record);
-
-
-/**
- * Destroy the specified SR instance.
- */
-extern bool
-xen_sr_destroy(xen_session *session, xen_sr sr);
-
-
-/**
* Get all the SR instances with the given label.
*/
extern bool
@@ -253,10 +240,10 @@ xen_sr_get_type(xen_session *session, char **result, xen_sr sr);
/**
- * Get the location field of the given SR.
+ * Get the content_type field of the given SR.
*/
extern bool
-xen_sr_get_location(xen_session *session, char **result, xen_sr sr);
+xen_sr_get_content_type(xen_session *session, char **result, xen_sr sr);
/**
@@ -274,11 +261,10 @@ xen_sr_set_name_description(xen_session *session, xen_sr sr, char *description);
/**
- * Take an exact copy of the Storage Repository; the cloned storage
- * repository has the same type as its parent
+ * Return a set of all the SR types supported by the system.
*/
extern bool
-xen_sr_clone(xen_session *session, xen_sr *result, xen_sr sr, char *loc, char *name);
+xen_sr_get_supported_types(xen_session *session, struct xen_string_set **result);
/**
diff --git a/tools/libxen/src/xen_sr.c b/tools/libxen/src/xen_sr.c
index 86538241a1..5220fa3019 100644
--- a/tools/libxen/src/xen_sr.c
+++ b/tools/libxen/src/xen_sr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -65,9 +65,9 @@ static const struct_member xen_sr_record_struct_members[] =
{ .key = "type",
.type = &abstract_type_string,
.offset = offsetof(xen_sr_record, type) },
- { .key = "location",
+ { .key = "content_type",
.type = &abstract_type_string,
- .offset = offsetof(xen_sr_record, location) }
+ .offset = offsetof(xen_sr_record, content_type) }
};
const abstract_type xen_sr_record_abstract_type_ =
@@ -94,7 +94,7 @@ xen_sr_record_free(xen_sr_record *record)
xen_vdi_record_opt_set_free(record->vdis);
xen_pbd_record_opt_set_free(record->pbds);
free(record->type);
- free(record->location);
+ free(record->content_type);
free(record);
}
@@ -140,24 +140,24 @@ xen_sr_get_by_uuid(xen_session *session, xen_sr *result, char *uuid)
bool
-xen_sr_create(xen_session *session, xen_sr *result, xen_sr_record *record)
+xen_sr_get_by_name_label(xen_session *session, struct xen_sr_set **result, char *label)
{
abstract_value param_values[] =
{
- { .type = &xen_sr_record_abstract_type_,
- .u.struct_val = record }
+ { .type = &abstract_type_string,
+ .u.string_val = label }
};
- abstract_type result_type = abstract_type_string;
+ abstract_type result_type = abstract_type_string_set;
*result = NULL;
- XEN_CALL_("SR.create");
+ XEN_CALL_("SR.get_by_name_label");
return session->ok;
}
bool
-xen_sr_destroy(xen_session *session, xen_sr sr)
+xen_sr_get_name_label(xen_session *session, char **result, xen_sr sr)
{
abstract_value param_values[] =
{
@@ -165,30 +165,16 @@ xen_sr_destroy(xen_session *session, xen_sr sr)
.u.string_val = sr }
};
- xen_call_(session, "SR.destroy", param_values, 1, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_sr_get_by_name_label(xen_session *session, struct xen_sr_set **result, char *label)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = label }
- };
-
- abstract_type result_type = abstract_type_string_set;
+ abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("SR.get_by_name_label");
+ XEN_CALL_("SR.get_name_label");
return session->ok;
}
bool
-xen_sr_get_name_label(xen_session *session, char **result, xen_sr sr)
+xen_sr_get_name_description(xen_session *session, char **result, xen_sr sr)
{
abstract_value param_values[] =
{
@@ -199,13 +185,13 @@ xen_sr_get_name_label(xen_session *session, char **result, xen_sr sr)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("SR.get_name_label");
+ XEN_CALL_("SR.get_name_description");
return session->ok;
}
bool
-xen_sr_get_name_description(xen_session *session, char **result, xen_sr sr)
+xen_sr_get_vdis(xen_session *session, struct xen_vdi_set **result, xen_sr sr)
{
abstract_value param_values[] =
{
@@ -213,16 +199,16 @@ xen_sr_get_name_description(xen_session *session, char **result, xen_sr sr)
.u.string_val = sr }
};
- abstract_type result_type = abstract_type_string;
+ abstract_type result_type = abstract_type_string_set;
*result = NULL;
- XEN_CALL_("SR.get_name_description");
+ XEN_CALL_("SR.get_VDIs");
return session->ok;
}
bool
-xen_sr_get_vdis(xen_session *session, struct xen_vdi_set **result, xen_sr sr)
+xen_sr_get_pbds(xen_session *session, struct xen_pbd_set **result, xen_sr sr)
{
abstract_value param_values[] =
{
@@ -233,7 +219,7 @@ xen_sr_get_vdis(xen_session *session, struct xen_vdi_set **result, xen_sr sr)
abstract_type result_type = abstract_type_string_set;
*result = NULL;
- XEN_CALL_("SR.get_VDIs");
+ XEN_CALL_("SR.get_PBDs");
return session->ok;
}
@@ -304,7 +290,7 @@ xen_sr_get_type(xen_session *session, char **result, xen_sr sr)
bool
-xen_sr_get_location(xen_session *session, char **result, xen_sr sr)
+xen_sr_get_content_type(xen_session *session, char **result, xen_sr sr)
{
abstract_value param_values[] =
{
@@ -315,7 +301,7 @@ xen_sr_get_location(xen_session *session, char **result, xen_sr sr)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("SR.get_location");
+ XEN_CALL_("SR.get_content_type");
return session->ok;
}
@@ -353,22 +339,13 @@ xen_sr_set_name_description(xen_session *session, xen_sr sr, char *description)
bool
-xen_sr_clone(xen_session *session, xen_sr *result, xen_sr sr, char *loc, char *name)
+xen_sr_get_supported_types(xen_session *session, struct xen_string_set **result)
{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = sr },
- { .type = &abstract_type_string,
- .u.string_val = loc },
- { .type = &abstract_type_string,
- .u.string_val = name }
- };
- abstract_type result_type = abstract_type_string;
+ abstract_type result_type = abstract_type_string_set;
*result = NULL;
- XEN_CALL_("SR.clone");
+ xen_call_(session, "SR.get_supported_types", NULL, 0, &result_type, result);
return session->ok;
}
diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py
index ff59cae102..0150d873cf 100644
--- a/tools/python/xen/xend/XendAPI.py
+++ b/tools/python/xen/xend/XendAPI.py
@@ -26,20 +26,22 @@ import threading
import time
import xmlrpclib
-from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
-from xen.xend import XendLogging, XendTaskManager
-
-from xen.xend.XendAPIVersion import *
-from xen.xend.XendAuthSessions import instance as auth_manager
-from xen.xend.XendError import *
-from xen.xend.XendClient import ERROR_INVALID_DOMAIN
-from xen.xend.XendLogging import log
-from xen.xend.XendNetwork import XendNetwork
-from xen.xend.XendTask import XendTask
-from xen.xend.XendPIFMetrics import XendPIFMetrics
-from xen.xend.XendVMMetrics import XendVMMetrics
-
-from xen.xend.XendAPIConstants import *
+import XendDomain, XendDomainInfo, XendNode, XendDmesg
+import XendLogging, XendTaskManager
+
+from XendAPIVersion import *
+from XendAuthSessions import instance as auth_manager
+from XendError import *
+from XendClient import ERROR_INVALID_DOMAIN
+from XendLogging import log
+from XendNetwork import XendNetwork
+from XendTask import XendTask
+from XendPIFMetrics import XendPIFMetrics
+from XendVMMetrics import XendVMMetrics
+
+import XendPBD
+
+from XendAPIConstants import *
from xen.util.xmlrpclib2 import stringify
from xen.util.blkif import blkdev_name_to_number
@@ -394,6 +396,17 @@ def valid_sr(func):
_check_ref(lambda r: XendNode.instance().is_valid_sr,
'SR', func, *args, **kwargs)
+def valid_pbd(func):
+ """Decorator to verify if pbd_ref is valid before calling
+ method.
+
+ @param func: function with params: (self, session, pbd_ref)
+ @rtype: callable object
+ """
+ return lambda *args, **kwargs: \
+ _check_ref(lambda r: r in XendPBD.get_all_refs(),
+ 'PBD', func, *args, **kwargs)
+
def valid_pif(func):
"""Decorator to verify if pif_ref is valid before calling
method.
@@ -479,6 +492,7 @@ classes = {
'VTPM' : valid_vtpm,
'console' : valid_console,
'SR' : valid_sr,
+ 'PBD' : valid_pbd,
'PIF' : valid_pif,
'PIF_metrics' : valid_pif_metrics,
'task' : valid_task,
@@ -488,6 +502,7 @@ classes = {
autoplug_classes = {
'network' : XendNetwork,
'VM_metrics' : XendVMMetrics,
+ 'PBD' : XendPBD.XendPBD,
'PIF_metrics' : XendPIFMetrics,
}
@@ -843,6 +858,7 @@ class XendAPI(object):
host_attr_ro = ['software_version',
'resident_VMs',
+ 'PBDs',
'PIFs',
'host_CPUs',
'cpu_configuration',
@@ -913,6 +929,8 @@ class XendAPI(object):
return xen_api_success(XendNode.instance().xen_version())
def host_get_resident_VMs(self, session, host_ref):
return xen_api_success(XendDomain.instance().get_domain_refs())
+ def host_get_PBDs(self, _, ref):
+ return xen_api_success(XendPBD.get_all_refs())
def host_get_PIFs(self, session, ref):
return xen_api_success(XendNode.instance().get_PIF_refs())
def host_get_host_CPUs(self, session, host_ref):
@@ -2434,18 +2452,17 @@ class XendAPI(object):
'physical_utilisation',
'physical_size',
'type',
- 'location']
+ 'content_type']
SR_attr_rw = ['name_label',
'name_description']
SR_attr_inst = ['physical_size',
'type',
- 'location',
'name_label',
'name_description']
- SR_methods = [('clone', 'SR'), ('destroy', None)]
+ SR_methods = []
SR_funcs = [('get_by_name_label', 'Set(SR)'),
('get_by_uuid', 'SR')]
@@ -2456,15 +2473,10 @@ class XendAPI(object):
def SR_get_by_name_label(self, session, label):
return xen_api_success(XendNode.instance().get_sr_by_name(label))
- def SR_create(self, session):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
+ def SR_get_supported_types(self, _):
+ return xen_api_success(['local', 'qcow_file'])
# Class Methods
- def SR_clone(self, session, sr_ref):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
-
- def SR_destroy(self, session, sr_ref):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
def SR_get_record(self, session, sr_ref):
sr = XendNode.instance().get_sr(sr_ref)
@@ -2497,8 +2509,8 @@ class XendAPI(object):
def SR_get_type(self, _, ref):
return self._get_SR_attr(ref, 'type')
- def SR_get_location(self, _, ref):
- return self._get_SR_attr(ref, 'location')
+ def SR_get_content_type(self, _, ref):
+ return self._get_SR_attr(ref, 'content_type')
def SR_get_name_label(self, _, ref):
return self._get_SR_attr(ref, 'name_label')
@@ -2521,6 +2533,33 @@ class XendAPI(object):
return xen_api_success_void()
+ # Xen API: Class PBD
+ # ----------------------------------------------------------------
+
+ PBD_attr_ro = ['host',
+ 'SR',
+ 'device_config',
+ 'currently_attached']
+ PBD_attr_rw = []
+ PBD_methods = [('destroy', None)]
+ PBD_funcs = [('create', None)]
+
+ def PBD_get_all(self, _):
+ return xen_api_success(XendPBD.get_all_refs())
+
+ def _PBD_get(self, _, ref):
+ return XendPBD.get(ref)
+
+ def PBD_create(self, _, record):
+ if 'uuid' in record:
+ return xen_api_error(['VALUE_NOT_SUPPORTED',
+ 'uuid', record['uuid'],
+ 'You may not specify a UUID on creation'])
+ new_uuid = XendPBD.XendPBD(record).get_uuid()
+ XendNode.instance().save()
+ return xen_api_success(new_uuid)
+
+
# Xen API: Class event
# ----------------------------------------------------------------
diff --git a/tools/python/xen/xend/XendLocalStorageRepo.py b/tools/python/xen/xend/XendLocalStorageRepo.py
index 9fa3926d5f..31b86f667b 100644
--- a/tools/python/xen/xend/XendLocalStorageRepo.py
+++ b/tools/python/xen/xend/XendLocalStorageRepo.py
@@ -30,13 +30,13 @@ import sys
import struct
from xen.util import mkdir
-from xen.xend import uuid
-from xen.xend.XendError import XendError
-from xen.xend.XendVDI import *
-from xen.xend.XendTask import XendTask
-from xen.xend.XendStorageRepository import XendStorageRepository
-from xen.xend.XendStateStore import XendStateStore
-from xen.xend.XendOptions import instance as xendoptions
+import uuid
+from XendError import XendError
+from XendVDI import *
+from XendTask import XendTask
+from XendStorageRepository import XendStorageRepository
+from XendStateStore import XendStateStore
+from XendOptions import instance as xendoptions
MB = 1024 * 1024
@@ -58,8 +58,7 @@ class XendLocalStorageRepo(XendStorageRepository):
"""
XendStorageRepository.__init__(self, sr_uuid, sr_type,
- name_label, name_description,
- '/')
+ name_label, name_description)
self.state = XendStateStore(xendoptions().get_xend_state_path()
+ '/local_sr')
diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py
index aad2ac7530..400686d8cb 100644
--- a/tools/python/xen/xend/XendNode.py
+++ b/tools/python/xen/xend/XendNode.py
@@ -22,17 +22,18 @@ import xen.lowlevel.xc
from xen.util import Brctl
-from xen.xend import uuid, arch
-from xen.xend.XendError import *
-from xen.xend.XendOptions import instance as xendoptions
-from xen.xend.XendQCoWStorageRepo import XendQCoWStorageRepo
-from xen.xend.XendLocalStorageRepo import XendLocalStorageRepo
-from xen.xend.XendLogging import log
-from xen.xend.XendPIF import *
-from xen.xend.XendPIFMetrics import XendPIFMetrics
-from xen.xend.XendNetwork import *
-from xen.xend.XendStateStore import XendStateStore
-from xen.xend.XendMonitor import XendMonitor
+import uuid, arch
+import XendPBD
+from XendError import *
+from XendOptions import instance as xendoptions
+from XendQCoWStorageRepo import XendQCoWStorageRepo
+from XendLocalStorageRepo import XendLocalStorageRepo
+from XendLogging import log
+from XendPIF import *
+from XendPIFMetrics import XendPIFMetrics
+from XendNetwork import *
+from XendStateStore import XendStateStore
+from XendMonitor import XendMonitor
class XendNode:
"""XendNode - Represents a Domain 0 Host."""
@@ -193,13 +194,14 @@ class XendNode:
saved_srs = self.state_store.load_state('sr')
if saved_srs:
for sr_uuid, sr_cfg in saved_srs.items():
+ log.error("SAved SRS %s %s", sr_uuid, sr_cfg['type'])
if sr_cfg['type'] == 'qcow_file':
self.srs[sr_uuid] = XendQCoWStorageRepo(sr_uuid)
- elif sr_cfg['type'] == 'local_image':
+ elif sr_cfg['type'] == 'local':
self.srs[sr_uuid] = XendLocalStorageRepo(sr_uuid)
# Create missing SRs if they don't exist
- if not self.get_sr_by_type('local_image'):
+ if not self.get_sr_by_type('local'):
image_sr_uuid = uuid.createString()
self.srs[image_sr_uuid] = XendLocalStorageRepo(image_sr_uuid)
@@ -207,6 +209,11 @@ class XendNode:
qcow_sr_uuid = uuid.createString()
self.srs[qcow_sr_uuid] = XendQCoWStorageRepo(qcow_sr_uuid)
+ saved_pbds = self.state_store.load_state('pbd')
+ if saved_pbds:
+ for pbd_uuid, pbd_cfg in saved_pbds.items():
+ pbd_cfg['uuid'] = pbd_uuid
+ XendPBD.XendPBD(pbd_cfg)
def network_create(self, record, persist = True, net_uuid = None):
@@ -280,6 +287,7 @@ class XendNode:
self.state_store.save_state('cpu', self.cpus)
self.save_PIFs()
self.save_networks()
+ self.save_PBDs()
self.save_SRs()
def save_PIFs(self):
@@ -292,6 +300,11 @@ class XendNode:
for k, v in self.networks.items()])
self.state_store.save_state('network', net_records)
+ def save_PBDs(self):
+ pbd_records = dict([(v.get_uuid(), v.get_record())
+ for v in XendPBD.get_all()])
+ self.state_store.save_state('pbd', pbd_records)
+
def save_SRs(self):
sr_records = dict([(k, v.get_record(transient = False))
for k, v in self.srs.items()])
diff --git a/tools/python/xen/xend/XendPBD.py b/tools/python/xen/xend/XendPBD.py
new file mode 100644
index 0000000000..0eab82781c
--- /dev/null
+++ b/tools/python/xen/xend/XendPBD.py
@@ -0,0 +1,79 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (c) 2007 Xensource Inc.
+#============================================================================
+
+
+import uuid
+from XendLogging import log
+
+
+attr_inst = ['uuid',
+ 'host',
+ 'SR',
+ 'device_config']
+attr_ro = attr_inst + ['currently_attached']
+
+
+_all = {}
+
+
+def get(ref):
+ return _all[ref]
+
+
+def get_all():
+ return _all.values()
+
+
+def get_all_refs():
+ return _all.keys()
+
+
+def get_by_SR(sr_ref):
+ return [k for (k, v) in _all.items() if v.get_SR() == sr_ref]
+
+
+class XendPBD:
+ """Physical block devices."""
+
+ def __init__(self, record):
+ if 'uuid' not in record:
+ record['uuid'] = uuid.createString()
+
+ import XendAPI
+ for v in attr_inst:
+ setattr(self, v, record[v])
+ self.currently_attached = True
+ _all[record['uuid']] = self
+
+
+ def destroy(self):
+ if self.uuid in _all:
+ del _all[self.uuid]
+
+
+ def get_record(self):
+ import XendAPI
+ result = {}
+ for v in attr_ro:
+ result[v] = getattr(self, v)
+ return result
+
+
+for v in attr_ro:
+ def f(v_):
+ setattr(XendPBD, 'get_' + v_, lambda s: getattr(s, v_))
+ f(v)
diff --git a/tools/python/xen/xend/XendQCoWStorageRepo.py b/tools/python/xen/xend/XendQCoWStorageRepo.py
index 80329d855c..425b4f7eca 100644
--- a/tools/python/xen/xend/XendQCoWStorageRepo.py
+++ b/tools/python/xen/xend/XendQCoWStorageRepo.py
@@ -29,12 +29,13 @@ import sys
import struct
from xen.util import mkdir
-from xen.xend import uuid
-from xen.xend.XendError import XendError
-from xen.xend.XendVDI import *
-from xen.xend.XendTask import XendTask
-from xen.xend.XendStorageRepository import XendStorageRepository
-from xen.xend.XendOptions import instance as xendoptions
+import uuid
+import XendPBD
+from XendError import XendError
+from XendVDI import *
+from XendTask import XendTask
+from XendStorageRepository import XendStorageRepository
+from XendOptions import instance as xendoptions
XEND_STORAGE_NO_MAXIMUM = sys.maxint
XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
@@ -72,7 +73,6 @@ class XendQCoWStorageRepo(XendStorageRepository):
sr_type = "qcow_file",
name_label = "QCoW",
name_description = "Xend QCoW Storage Repository",
- location = xendoptions().get_xend_storage_path(),
storage_max = XEND_STORAGE_NO_MAXIMUM):
"""
@keyword storage_max: Maximum disk space to use in bytes.
@@ -85,9 +85,9 @@ class XendQCoWStorageRepo(XendStorageRepository):
"""
XendStorageRepository.__init__(self, sr_uuid, sr_type, name_label,
- name_description, location,
- storage_max)
+ name_description, storage_max)
self.storage_free = 0
+ self.location = xendoptions().get_xend_storage_path()
self._refresh()
def get_record(self, transient = True):
@@ -98,8 +98,9 @@ class XendQCoWStorageRepo(XendStorageRepository):
'physical_utilisation': self.physical_utilisation,
'physical_size': self.physical_size,
'type': self.type,
- 'location': self.location,
- 'VDIs': self.images.keys()}
+ 'content_type': self.content_type,
+ 'VDIs': self.images.keys(),
+ 'PBDs': XendPBD.get_by_SR(self.uuid)}
if self.physical_size == XEND_STORAGE_NO_MAXIMUM:
stfs = os.statvfs(self.location)
diff --git a/tools/python/xen/xend/XendStateStore.py b/tools/python/xen/xend/XendStateStore.py
index 8bea86ec95..46a33d1b25 100644
--- a/tools/python/xen/xend/XendStateStore.py
+++ b/tools/python/xen/xend/XendStateStore.py
@@ -204,7 +204,7 @@ class XendStateStore:
if type(val) == dict:
for val_uuid in val.keys():
val_node = doc.createElement(key)
- if key == 'other_config':
+ if key in ['other_config', 'device_config']:
val_node.setAttribute('key', str(val_uuid))
val_node.setAttribute('value', str(val[val_uuid]))
else:
diff --git a/tools/python/xen/xend/XendStorageRepository.py b/tools/python/xen/xend/XendStorageRepository.py
index 54ba0ea3e6..1e096cdf91 100644
--- a/tools/python/xen/xend/XendStorageRepository.py
+++ b/tools/python/xen/xend/XendStorageRepository.py
@@ -22,8 +22,9 @@
import threading
import sys
-from xen.xend.XendError import XendError
-from xen.xend.XendVDI import *
+from XendError import XendError
+from XendVDI import *
+import XendPBD
XEND_STORAGE_NO_MAXIMUM = sys.maxint
@@ -34,7 +35,6 @@ class XendStorageRepository:
sr_type = "unknown",
name_label = 'Unknown',
name_description = 'Not Implemented',
- location = '',
storage_max = XEND_STORAGE_NO_MAXIMUM):
"""
@keyword storage_max: Maximum disk space to use in bytes.
@@ -49,7 +49,6 @@ class XendStorageRepository:
# XenAPI Parameters
self.uuid = uuid
self.type = sr_type
- self.location = location
self.name_label = name_label
self.name_description = name_description
self.images = {}
@@ -57,6 +56,7 @@ class XendStorageRepository:
self.physical_size = storage_max
self.physical_utilisation = 0
self.virtual_allocation = 0
+ self.content_type = ''
self.lock = threading.RLock()
@@ -68,9 +68,10 @@ class XendStorageRepository:
'physical_utilisation': self.physical_utilisation,
'physical_size': self.physical_size,
'type': self.type,
- 'location': self.location,
+ 'content_type': self.content_type,
'VDIs': self.images.keys()}
-
+ if not transient:
+ retval ['PBDs'] = XendPBD.get_by_SR(self.uuid)
return retval