[DRBD-user] State change failed: Device is held open by someone

Satyajit Paul satyajit.paul at aricent.com
Fri Mar 8 12:37:23 CET 2013

Note: "permalinks" may not be as permanent as we would like,
direct links of old sources may well be a few messages off.


When I wanted to change the state of DRBD from primary to secondary, sometimes I get the "Device is held open by someone" issue.
I looked into the code drbd_main.c (DRBD Release 8.0.11) and found that the error is set from the below code.

    else if( ns.role == Secondary && mdev->open_cnt )

I put debug logs and found that sometimes "open_cnt" variable is not equal to zero that results in the error. "open_cnt" variable is incremented and decremented from the function drbd_open() and drbd_close() respectively. In function drbd_open(), "open_cnt" variable is handled within locking/unlocking function to avoid race condition whereas in drbd_close(), no such locking/unlocking function is there to handle its critical section. Can we imagine any scenario that due to the absence of locking/unlocking function in the drbd_close() function, race condition is occurring that results in the wrong value of "open_cnt" variable.

Here is the code.

STATIC int drbd_close(struct inode *inode, struct file *file)
                        /* do not use *file (May be NULL, in case of a unmount :-) */
                        drbd_dev *mdev;

                        mdev = minor_to_mdev(MINOR(inode->i_rdev));
                        if(!mdev) return -ENODEV;

                        printk(KERN_ERR DEVICE_NAME ": close(inode=%p,file=%p)"
                               "current=%p,minor=%d,wc=%d\n", inode, file, current, minor,


                        return 0;

STATIC int drbd_open(struct inode *inode, struct file *file)
                        drbd_dev *mdev;
                        unsigned long flags;
                        int rv=0;

                        mdev = minor_to_mdev(MINOR(inode->i_rdev));
                        if(!mdev) return -ENODEV;

                        /* to have a stable mdev->state.role and no race with updating open_cnt */

                        if (mdev->state.role != Primary) {
                                                if (file->f_mode & FMODE_WRITE) {
                                                                        rv = -EROFS;
                                                } else if (!allow_oos) {
                                                                        rv = -EMEDIUMTYPE;

                        if(!rv) mdev->open_cnt++;

                        return rv;

Thanks in Advance.

Satyajit Paul
Software Engineer

Please refer to http://www.aricent.com/legal/email_disclaimer.html
for important disclosures regarding this electronic communication.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linbit.com/pipermail/drbd-user/attachments/20130308/f8369bbc/attachment.htm>

More information about the drbd-user mailing list