virSecurityManagerSetSocketLabel;
virSecurityManagerSetTapFDLabel;
virSecurityManagerStackAddNested;
+virSecurityManagerTransactionAbort;
+virSecurityManagerTransactionCommit;
+virSecurityManagerTransactionStart;
virSecurityManagerVerify;
typedef int (*virSecurityDriverPreFork) (virSecurityManagerPtr mgr);
+typedef int (*virSecurityDriverTransactionStart) (virSecurityManagerPtr mgr);
+typedef int (*virSecurityDriverTransactionCommit) (virSecurityManagerPtr mgr,
+ pid_t pid);
+typedef void (*virSecurityDriverTransactionAbort) (virSecurityManagerPtr mgr);
+
typedef int (*virSecurityDomainRestoreDiskLabel) (virSecurityManagerPtr mgr,
virDomainDefPtr def,
virDomainDiskDefPtr disk);
virSecurityDriverPreFork preFork;
+ virSecurityDriverTransactionStart transactionStart;
+ virSecurityDriverTransactionCommit transactionCommit;
+ virSecurityDriverTransactionAbort transactionAbort;
+
virSecurityDomainSecurityVerify domainSecurityVerify;
virSecurityDomainSetDiskLabel domainSetSecurityDiskLabel;
virObjectUnlock(mgr);
}
+
+/**
+ * virSecurityManagerTransactionStart:
+ * @mgr: security manager
+ *
+ * Starts a new transaction. In transaction nothing is changed security
+ * label until virSecurityManagerTransactionCommit() is called.
+ *
+ * Returns 0 on success,
+ * -1 otherwise.
+ */
+int
+virSecurityManagerTransactionStart(virSecurityManagerPtr mgr)
+{
+ int ret = 0;
+
+ virObjectLock(mgr);
+ if (mgr->drv->transactionStart)
+ ret = mgr->drv->transactionStart(mgr);
+ virObjectUnlock(mgr);
+ return ret;
+}
+
+
+/**
+ * virSecurityManagerTransactionCommit:
+ * @mgr: security manager
+ * @pid: domain's PID
+ *
+ * Enters the @pid namespace (usually @pid refers to a domain) and
+ * performs all the operations on the transaction list. Note that the
+ * transaction is also freed, therefore new one has to be started after
+ * successful return from this function. Also it is considered as error
+ * if there's no transaction set and this function is called.
+ *
+ * Returns: 0 on success,
+ * -1 otherwise.
+ */
+int
+virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr,
+ pid_t pid)
+{
+ int ret = 0;
+
+ virObjectLock(mgr);
+ if (mgr->drv->transactionCommit)
+ ret = mgr->drv->transactionCommit(mgr, pid);
+ virObjectUnlock(mgr);
+ return ret;
+}
+
+
+/**
+ * virSecurityManagerTransactionAbort:
+ * @mgr: security manager
+ *
+ * Cancels and frees any out standing transaction.
+ */
+void
+virSecurityManagerTransactionAbort(virSecurityManagerPtr mgr)
+{
+ virObjectLock(mgr);
+ if (mgr->drv->transactionAbort)
+ mgr->drv->transactionAbort(mgr);
+ virObjectUnlock(mgr);
+}
+
+
void *
virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
{
int virSecurityManagerPreFork(virSecurityManagerPtr mgr);
void virSecurityManagerPostFork(virSecurityManagerPtr mgr);
+int virSecurityManagerTransactionStart(virSecurityManagerPtr mgr);
+int virSecurityManagerTransactionCommit(virSecurityManagerPtr mgr,
+ pid_t pid);
+void virSecurityManagerTransactionAbort(virSecurityManagerPtr mgr);
+
void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
const char *virSecurityManagerGetDriver(virSecurityManagerPtr mgr);
return rc;
}
+
+static int
+virSecurityStackTransactionStart(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
+ int rc = 0;
+
+ for (; item; item = item->next) {
+ if (virSecurityManagerTransactionStart(item->securityManager) < 0)
+ rc = -1;
+ }
+
+ return rc;
+}
+
+
+static int
+virSecurityStackTransactionCommit(virSecurityManagerPtr mgr,
+ pid_t pid)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
+ int rc = 0;
+
+ for (; item; item = item->next) {
+ if (virSecurityManagerTransactionCommit(item->securityManager, pid) < 0)
+ rc = -1;
+ }
+
+ return rc;
+}
+
+
+static void
+virSecurityStackTransactionAbort(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
+
+ for (; item; item = item->next)
+ virSecurityManagerTransactionAbort(item->securityManager);
+}
+
+
static int
virSecurityStackVerify(virSecurityManagerPtr mgr,
virDomainDefPtr def)
.preFork = virSecurityStackPreFork,
+ .transactionStart = virSecurityStackTransactionStart,
+ .transactionCommit = virSecurityStackTransactionCommit,
+ .transactionAbort = virSecurityStackTransactionAbort,
+
.domainSecurityVerify = virSecurityStackVerify,
.domainSetSecurityDiskLabel = virSecurityStackSetDiskLabel,