static int virLockManagerSanlockAcquire(virLockManagerPtr lock, const char *state, unsigned int flags, virDomainLockFailureAction action, int *fd) { virLockManagerSanlockPrivatePtr priv = lock->privateData; struct sanlk_options *opt; struct sanlk_resource **res_args; int res_count; bool res_free = false; int sock = -1; int rv; int i; virCheckFlags(VIR_LOCK_MANAGER_ACQUIRE_RESTRICT | VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY, -1); if (priv->res_count == 0 && priv->hasRWDisks && driver->requireLeaseForDisks) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Read/write, exclusive access, disks were present, but no leases specified")); return -1; } if (VIR_ALLOC(opt) < 0) { virReportOOMError(); return -1; } if (!virStrcpy(opt->owner_name, priv->vm_name, SANLK_NAME_LEN)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Domain name '%s' exceeded %d characters"), priv->vm_name, SANLK_NAME_LEN); goto error; } if (state && STRNEQ(state, "")) { if ((rv = sanlock_state_to_args((char *)state, &res_count, &res_args)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to parse lock state %s: error %d"), state, rv); else virReportSystemError(-rv, _("Unable to parse lock state %s"), state); goto error; } res_free = true; } else { res_args = priv->res_args; res_count = priv->res_count; } /* We only initialize 'sock' if we are in the real * child process and we need it to be inherited * * If sock==-1, then sanlock auto-open/closes a * temporary sock */ if (priv->vm_pid == getpid()) { VIR_DEBUG("Register sanlock %d", flags); if ((sock = sanlock_register()) < 0) { if (sock <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to open socket to sanlock daemon: error %d"), sock); else virReportSystemError(-sock, "%s", _("Failed to open socket to sanlock daemon")); goto error; } if (action != VIR_DOMAIN_LOCK_FAILURE_DEFAULT) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(priv->vm_uuid, uuidstr); if (virLockManagerSanlockRegisterKillscript(sock, priv->vm_uri, uuidstr, action) < 0) goto error; } } if (!(flags & VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY)) { VIR_DEBUG("Acquiring object %u", priv->res_count); if ((rv = sanlock_acquire(sock, priv->vm_pid, 0, priv->res_count, priv->res_args, opt)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to acquire lock: error %d"), rv); else virReportSystemError(-rv, "%s", _("Failed to acquire lock")); goto error; } } VIR_FREE(opt); /* * We are *intentionally* "leaking" sock file descriptor * because we want it to be inherited by QEMU. When the * sock FD finally closes upon QEMU exit (or crash) then * sanlock will notice EOF and release the lock */ if (sock != -1 && virSetInherit(sock, true) < 0) goto error; if (flags & VIR_LOCK_MANAGER_ACQUIRE_RESTRICT) { if ((rv = sanlock_restrict(sock, SANLK_RESTRICT_ALL)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to restrict process: error %d"), rv); else virReportSystemError(-rv, "%s", _("Failed to restrict process")); goto error; } } VIR_DEBUG("Acquire completed fd=%d", sock); if (res_free) { for (i = 0 ; i < res_count ; i++) { VIR_FREE(res_args[i]); } VIR_FREE(res_args); } if (fd) *fd = sock; return 0; error: if (res_free) { for (i = 0 ; i < res_count ; i++) { VIR_FREE(res_args[i]); } VIR_FREE(res_args); } VIR_FREE(opt); VIR_FORCE_CLOSE(sock); return -1; }
exit_fail: free(res); return -1; } /* register */ PyDoc_STRVAR(pydoc_register, "\ register() -> int\n\ Register to sanlock daemon and return the connection fd."); static PyObject * py_register(PyObject *self __unused, PyObject *args) { int sanlockfd; sanlockfd = sanlock_register(); if (sanlockfd < 0) { __set_exception(sanlockfd, "Sanlock registration failed"); return NULL; } return PyInt_FromLong(sanlockfd); } /* get_alignment */ PyDoc_STRVAR(pydoc_get_alignment, "\ get_alignment(path) -> int\n\ Get device alignment."); static PyObject *