if (!try_module_get(THIS_MODULE))
                return -EINVAL;
 
+       if (!dlm_user_daemon_available()) {
+               module_put(THIS_MODULE);
+               return -EUNATCH;
+       }
+
        error = 0;
 
        spin_lock(&lslist_lock);
 
        dlm_device_deregister(ls);
 
-       if (force < 3)
+       if (force < 3 && dlm_user_daemon_available())
                do_uevent(ls, 0);
 
        dlm_recoverd_stop(ls);
        return error;
 }
 
+void dlm_stop_lockspaces(void)
+{
+       struct dlm_ls *ls;
+
+ restart:
+       spin_lock(&lslist_lock);
+       list_for_each_entry(ls, &lslist, ls_list) {
+               if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
+                       continue;
+               spin_unlock(&lslist_lock);
+               log_error(ls, "no userland control daemon, stopping lockspace");
+               dlm_ls_stop(ls);
+               goto restart;
+       }
+       spin_unlock(&lslist_lock);
+}
+
 
 
 static const char name_prefix[] = "dlm";
 static const struct file_operations device_fops;
+static atomic_t dlm_monitor_opened;
+static int dlm_monitor_unused = 1;
 
 #ifdef CONFIG_COMPAT
 
        return 0;
 }
 
+int dlm_user_daemon_available(void)
+{
+       /* dlm_controld hasn't started (or, has started, but not
+          properly populated configfs) */
+
+       if (!dlm_our_nodeid())
+               return 0;
+
+       /* This is to deal with versions of dlm_controld that don't
+          know about the monitor device.  We assume that if the
+          dlm_controld was started (above), but the monitor device
+          was never opened, that it's an old version.  dlm_controld
+          should open the monitor device before populating configfs. */
+
+       if (dlm_monitor_unused)
+               return 1;
+
+       return atomic_read(&dlm_monitor_opened) ? 1 : 0;
+}
+
 static int ctl_device_open(struct inode *inode, struct file *file)
 {
        cycle_kernel_lock();
        return 0;
 }
 
+static int monitor_device_open(struct inode *inode, struct file *file)
+{
+       atomic_inc(&dlm_monitor_opened);
+       dlm_monitor_unused = 0;
+       return 0;
+}
+
+static int monitor_device_close(struct inode *inode, struct file *file)
+{
+       if (atomic_dec_and_test(&dlm_monitor_opened))
+               dlm_stop_lockspaces();
+       return 0;
+}
+
 static const struct file_operations device_fops = {
        .open    = device_open,
        .release = device_close,
        .minor = MISC_DYNAMIC_MINOR,
 };
 
+static const struct file_operations monitor_device_fops = {
+       .open    = monitor_device_open,
+       .release = monitor_device_close,
+       .owner   = THIS_MODULE,
+};
+
+static struct miscdevice monitor_device = {
+       .name  = "dlm-monitor",
+       .fops  = &monitor_device_fops,
+       .minor = MISC_DYNAMIC_MINOR,
+};
+
 int __init dlm_user_init(void)
 {
        int error;
 
+       atomic_set(&dlm_monitor_opened, 0);
+
        error = misc_register(&ctl_device);
-       if (error)
+       if (error) {
                log_print("misc_register failed for control device");
+               goto out;
+       }
 
+       error = misc_register(&monitor_device);
+       if (error) {
+               log_print("misc_register failed for monitor device");
+               misc_deregister(&ctl_device);
+       }
+ out:
        return error;
 }
 
 void dlm_user_exit(void)
 {
        misc_deregister(&ctl_device);
+       misc_deregister(&monitor_device);
 }