diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index ad3495a804..3b2d104f03 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1530,7 +1530,7 @@ static void devices_destroy_cb(libxl__egc *egc, uint32_t domid = dis->domid; char *dom_path; char *vm_path; - libxl__carefd *lock = NULL; + libxl__domain_userdata_lock *lock = NULL; dom_path = libxl__xs_get_dompath(gc, domid); if (!dom_path) { diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index a5e185eac6..8b825849d1 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -1404,7 +1404,7 @@ static void domcreate_complete(libxl__egc *egc, rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref); if (!rc) { - libxl__carefd *lock; + libxl__domain_userdata_lock *lock; /* Note that we hold CTX lock at this point so only need to * take data store lock diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 0dfdb088d5..02384acdf7 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -1857,8 +1857,12 @@ void libxl__userdata_destroyall(libxl__gc *gc, uint32_t domid) if (r) LOGE(ERROR, "glob failed for %s", pattern); + /* Note: don't delete domain-userdata-lock, it will be handled by + * unlock function. + */ for (i=0; ipath = libxl__strdup(NOGC, lockfile); + while (true) { libxl__carefd_begin(); fd = open(lockfile, O_RDWR|O_CREAT, 0666); if (fd < 0) LOGE(ERROR, "cannot open lockfile %s, errno=%d", lockfile, errno); - carefd = libxl__carefd_opened(CTX, fd); + lock->lock_carefd = libxl__carefd_opened(CTX, fd); if (fd < 0) goto out; /* Lock the file in exclusive mode, wait indefinitely to @@ -434,20 +438,28 @@ libxl__carefd *libxl__lock_domain_userdata(libxl__gc *gc, uint32_t domid) break; } - libxl__carefd_close(carefd); + libxl__carefd_close(lock->lock_carefd); } - return carefd; + /* Check the domain is still there, if not we should release the + * lock and clean up. + */ + if (libxl_domain_info(CTX, NULL, domid)) + goto out; + + return lock; out: - if (carefd) libxl__carefd_close(carefd); + if (lock) libxl__unlock_domain_userdata(lock); return NULL; } -void libxl__unlock_domain_userdata(libxl__carefd *lock_carefd) +void libxl__unlock_domain_userdata(libxl__domain_userdata_lock *lock) { - /* Simply closing the file descriptor releases the lock */ - libxl__carefd_close(lock_carefd); + if (lock->path) unlink(lock->path); + if (lock->lock_carefd) libxl__carefd_close(lock->lock_carefd); + free(lock->path); + free(lock); } int libxl__get_domain_configuration(libxl__gc *gc, uint32_t domid, diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 03e9978553..aa18e74711 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -3241,8 +3241,13 @@ static inline int libxl__key_value_list_is_empty(libxl_key_value_list *pkvl) int libxl__cpuid_policy_is_empty(libxl_cpuid_policy_list *pl); /* Portability note: a proper flock(2) implementation is required */ -libxl__carefd *libxl__lock_domain_userdata(libxl__gc *gc, uint32_t domid); -void libxl__unlock_domain_userdata(libxl__carefd *lock_carefd); +typedef struct { + libxl__carefd *lock_carefd; + char *path; /* path of the lock file itself */ +} libxl__domain_userdata_lock; +libxl__domain_userdata_lock *libxl__lock_domain_userdata(libxl__gc *gc, + uint32_t domid); +void libxl__unlock_domain_userdata(libxl__domain_userdata_lock *lock); /* * Retrieve / store domain configuration from / to libxl private