aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamian Hobson-Garcia <dhobsong@igel.co.jp>2021-03-22 11:54:16 +0900
committerDamian Hobson-Garcia <dhobsong@igel.co.jp>2021-04-06 15:58:47 +0900
commitbd9df88e70982fb0de81664ebf928d1a414d2887 (patch)
tree813254108a519a28430746dca668307bea6139fd
parent165bb55a61361306ded5b35aace4f660f99714be (diff)
Add option to hold lease on unexpected disconnect
If a client application crashes while owning a lease, the lease will automatically be revoked and all references freed to make it available for another (or the restarted original) client to claim and continue display. This will cause the screen to blank while the lease is unowned. Add an option to revoke the lease, but keep the reference to the lease descriptor, so that the screen does not blank while unowned. This only has effect when a client exits without calling the `dlm_release_lease` function. Otherwise the lease is revoked and the descriptor dereferenced, just as before. Bug-AGL: SPEC-3862 Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp> Change-Id: I3fc2c8fde4118b6e298ba31807fd5fa4766a97dd
-rw-r--r--drm-lease-manager/lease-manager.c33
-rw-r--r--drm-lease-manager/lease-manager.h1
-rw-r--r--drm-lease-manager/lease-server.c2
-rw-r--r--drm-lease-manager/lease-server.h1
-rw-r--r--drm-lease-manager/main.c15
5 files changed, 40 insertions, 12 deletions
diff --git a/drm-lease-manager/lease-manager.c b/drm-lease-manager/lease-manager.c
index 5d79b8d..cfb1ab5 100644
--- a/drm-lease-manager/lease-manager.c
+++ b/drm-lease-manager/lease-manager.c
@@ -331,6 +331,7 @@ static struct lease *lease_create(struct lm *lm, drmModeConnectorPtr connector)
lease->object_ids[lease->nobject_ids++] = connector->connector_id;
lease->is_granted = false;
+ lease->lease_fd = -1;
return lease;
@@ -417,7 +418,9 @@ void lm_destroy(struct lm *lm)
assert(lm);
for (int i = 0; i < lm->nleases; i++) {
- lm_lease_revoke(lm, (struct lease_handle *)lm->leases[i]);
+ struct lease_handle *lease_handle = &lm->leases[i]->base;
+ lm_lease_revoke(lm, lease_handle);
+ lm_lease_close(lease_handle);
lease_free(lm->leases[i]);
}
@@ -448,17 +451,24 @@ int lm_lease_grant(struct lm *lm, struct lease_handle *handle)
return -1;
}
- lease->lease_fd =
+ int lease_fd =
drmModeCreateLease(lm->drm_fd, lease->object_ids,
lease->nobject_ids, 0, &lease->lessee_id);
- if (lease->lease_fd < 0) {
+ if (lease_fd < 0) {
ERROR_LOG("drmModeCreateLease failed on lease %s: %s\n",
lease->base.name, strerror(errno));
return -1;
}
lease->is_granted = true;
- return lease->lease_fd;
+
+ int old_lease_fd = lease->lease_fd;
+ lease->lease_fd = lease_fd;
+
+ if (old_lease_fd >= 0)
+ close_after_lease_transition(lease, old_lease_fd);
+
+ return lease_fd;
}
int lm_lease_transfer(struct lm *lm, struct lease_handle *handle)
@@ -470,15 +480,12 @@ int lm_lease_transfer(struct lm *lm, struct lease_handle *handle)
if (!lease->is_granted)
return -1;
- int old_lease_fd = dup(lease->lease_fd);
-
lm_lease_revoke(lm, handle);
if (lm_lease_grant(lm, handle) < 0) {
- close(old_lease_fd);
+ lm_lease_close(handle);
return -1;
}
- close_after_lease_transition(lease, old_lease_fd);
return lease->lease_fd;
}
@@ -494,6 +501,14 @@ void lm_lease_revoke(struct lm *lm, struct lease_handle *handle)
drmModeRevokeLease(lm->drm_fd, lease->lessee_id);
cancel_lease_transition_thread(lease);
- close(lease->lease_fd);
lease->is_granted = false;
}
+
+void lm_lease_close(struct lease_handle *handle)
+{
+ assert(handle);
+
+ struct lease *lease = (struct lease *)handle;
+ close(lease->lease_fd);
+ lease->lease_fd = -1;
+}
diff --git a/drm-lease-manager/lease-manager.h b/drm-lease-manager/lease-manager.h
index 581e05c..55bf81e 100644
--- a/drm-lease-manager/lease-manager.h
+++ b/drm-lease-manager/lease-manager.h
@@ -27,4 +27,5 @@ int lm_get_lease_handles(struct lm *lm, struct lease_handle ***lease_handles);
int lm_lease_grant(struct lm *lm, struct lease_handle *lease_handle);
int lm_lease_transfer(struct lm *lm, struct lease_handle *lease_handle);
void lm_lease_revoke(struct lm *lm, struct lease_handle *lease_handle);
+void lm_lease_close(struct lease_handle *lease_handle);
#endif
diff --git a/drm-lease-manager/lease-server.c b/drm-lease-manager/lease-server.c
index c81d363..a7e3190 100644
--- a/drm-lease-manager/lease-server.c
+++ b/drm-lease-manager/lease-server.c
@@ -329,7 +329,7 @@ bool ls_get_request(struct ls *ls, struct ls_req *req)
request = parse_client_request(sock);
if (request < 0 && (ev.events & POLLHUP))
- request = LS_REQ_RELEASE_LEASE;
+ request = LS_REQ_CLIENT_DISCONNECT;
struct ls_client *client = sock->client;
struct ls_server *server = client->serv;
diff --git a/drm-lease-manager/lease-server.h b/drm-lease-manager/lease-server.h
index 1aaad30..823d340 100644
--- a/drm-lease-manager/lease-server.h
+++ b/drm-lease-manager/lease-server.h
@@ -24,6 +24,7 @@ struct ls_client;
enum ls_req_type {
LS_REQ_GET_LEASE,
LS_REQ_RELEASE_LEASE,
+ LS_REQ_CLIENT_DISCONNECT,
};
struct ls_req {
diff --git a/drm-lease-manager/main.c b/drm-lease-manager/main.c
index 78ff0df..2927253 100644
--- a/drm-lease-manager/main.c
+++ b/drm-lease-manager/main.c
@@ -28,15 +28,17 @@ static void usage(const char *progname)
"Options:\n"
"-h, --help \tPrint this help\n"
"-v, --verbose \tEnable verbose debug messages\n"
- "-t, --lease-transfer \tAllow lease transfter to new clients\n",
+ "-t, --lease-transfer \tAllow lease transfter to new clients\n"
+ "-k, --keep-on-crash \tDon't close lease on client crash\n",
progname);
}
-const char *opts = "vth";
+const char *opts = "vtkh";
const struct option options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{"lease-transfer", no_argument, NULL, 't'},
+ {"keep-on-crash", no_argument, NULL, 'k'},
{NULL, 0, NULL, 0},
};
@@ -46,6 +48,7 @@ int main(int argc, char **argv)
bool debug_log = false;
bool can_transfer_leases = false;
+ bool keep_on_crash = false;
int c;
while ((c = getopt_long(argc, argv, opts, options, NULL)) != -1) {
@@ -57,6 +60,9 @@ int main(int argc, char **argv)
case 't':
can_transfer_leases = true;
break;
+ case 'k':
+ keep_on_crash = true;
+ break;
case 'h':
ret = EXIT_SUCCESS;
/* fall through */
@@ -122,9 +128,14 @@ int main(int argc, char **argv)
break;
}
case LS_REQ_RELEASE_LEASE:
+ case LS_REQ_CLIENT_DISCONNECT:
ls_disconnect_client(ls, req.client);
req.lease_handle->user_data = NULL;
lm_lease_revoke(lm, req.lease_handle);
+
+ if (!keep_on_crash || req.type == LS_REQ_RELEASE_LEASE)
+ lm_lease_close(req.lease_handle);
+
break;
default:
ERROR_LOG("Internal error: Invalid lease request\n");