Add option to hold lease on unexpected disconnect
[src/drm-lease-manager.git] / drm-lease-manager / main.c
index c3a933f..2927253 100644 (file)
@@ -27,14 +27,18 @@ static void usage(const char *progname)
        printf("Usage: %s [OPTIONS] [<DRM device>]\n\n"
               "Options:\n"
               "-h, --help \tPrint this help\n"
-              "-v, --verbose \tEnable verbose debug messages\n",
+              "-v, --verbose \tEnable verbose debug messages\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 = "vh";
+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},
 };
 
@@ -43,6 +47,8 @@ int main(int argc, char **argv)
        char *device = "/dev/dri/card0";
 
        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) {
@@ -51,6 +57,12 @@ int main(int argc, char **argv)
                case 'v':
                        debug_log = true;
                        break;
+               case 't':
+                       can_transfer_leases = true;
+                       break;
+               case 'k':
+                       keep_on_crash = true;
+                       break;
                case 'h':
                        ret = EXIT_SUCCESS;
                        /* fall through */
@@ -87,26 +99,43 @@ int main(int argc, char **argv)
                switch (req.type) {
                case LS_REQ_GET_LEASE: {
                        int fd = lm_lease_grant(lm, req.lease_handle);
+
+                       if (fd < 0 && can_transfer_leases)
+                               fd = lm_lease_transfer(lm, req.lease_handle);
+
                        if (fd < 0) {
                                ERROR_LOG(
                                    "Can't fulfill lease request: lease=%s\n",
                                    req.lease_handle->name);
-                               ls_disconnect_client(ls, req.server);
+                               ls_disconnect_client(ls, req.client);
                                break;
                        }
 
-                       if (!ls_send_fd(ls, req.server, fd)) {
+                       struct ls_client *active_client =
+                           req.lease_handle->user_data;
+                       if (active_client)
+                               ls_disconnect_client(ls, active_client);
+
+                       req.lease_handle->user_data = req.client;
+
+                       if (!ls_send_fd(ls, req.client, fd)) {
                                ERROR_LOG(
                                    "Client communication error: lease=%s\n",
                                    req.lease_handle->name);
-                               ls_disconnect_client(ls, req.server);
+                               ls_disconnect_client(ls, req.client);
                                lm_lease_revoke(lm, req.lease_handle);
                        }
                        break;
                }
                case LS_REQ_RELEASE_LEASE:
-                       ls_disconnect_client(ls, req.server);
+               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");