vkernel - Add support for cdevs as virtual disks
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 26 Sep 2010 04:00:04 +0000 (21:00 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 26 Sep 2010 04:00:04 +0000 (21:00 -0700)
* Allow a cdev to be directly specified as a virtual disk.

sys/dev/virtual/disk/vdisk.c
sys/platform/vkernel/platform/init.c
sys/platform/vkernel64/platform/init.c

index 70f225f..a657273 100644 (file)
@@ -102,6 +102,16 @@ vkdinit(void *dummy __unused)
                if (dsk->fd < 0 || fstat(dsk->fd, &st) < 0)
                        continue;
 
+               /*
+                * Devices may return a st_size of 0, try to use
+                * lseek.
+                */
+               if (st.st_size == 0) {
+                       st.st_size = lseek(dsk->fd, 0L, SEEK_END);
+                       if (st.st_size == -1)
+                               st.st_size = 0;
+               }
+
                /* and create a new device */
                sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
                sc->unit = dsk->unit;
index ba07d25..3f37eff 100644 (file)
@@ -728,18 +728,20 @@ init_disk(char *diskExp[], int diskFileNum, enum vkdisk_type type)
                                size_t l = 0;
 
                        if (type == VKD_DISK)
-                           fd = open(fname, O_RDWR|O_DIRECT|O_EXLOCK|O_NONBLOCK, 0644);
+                           fd = open(fname, O_RDWR|O_DIRECT, 0644);
                        else
                            fd = open(fname, O_RDONLY|O_DIRECT, 0644);
                        if (fd < 0 || fstat(fd, &st) < 0) {
-                               if (errno == EAGAIN)
-                                       fprintf(stderr, "You may already have a vkernel using this disk image!\n");
                                err(1, "Unable to open/create %s", fname);
                                /* NOT REACHED */
                        }
-                       /* get rid of O_NONBLOCK, keep O_DIRECT */
-                       if (type == VKD_DISK)
-                               fcntl(fd, F_SETFL, O_DIRECT);
+                       if (S_ISREG(st.st_mode)) {
+                               if (flock(fd, LOCK_EX|LOCK_NB) < 0) {
+                                       errx(1, "Disk image %s is already "
+                                               "in use\n", fname);
+                                       /* NOT REACHED */
+                               }
+                       }
 
                        info = &DiskInfo[DiskNum];
                        l = strlen(fname);
index 2c859b1..4bf17e2 100644 (file)
@@ -691,18 +691,20 @@ init_disk(char *diskExp[], int diskFileNum, enum vkdisk_type type)
                        size_t l = 0;
 
                        if (type == VKD_DISK)
-                           fd = open(fname, O_RDWR|O_DIRECT|O_EXLOCK|O_NONBLOCK, 0644);
+                           fd = open(fname, O_RDWR|O_DIRECT, 0644);
                        else
                            fd = open(fname, O_RDONLY|O_DIRECT, 0644);
                        if (fd < 0 || fstat(fd, &st) < 0) {
-                               if (errno == EAGAIN)
-                                       fprintf(stderr, "You may already have a vkernel using this disk image!\n");
                                err(1, "Unable to open/create %s", fname);
                                /* NOT REACHED */
                        }
-                       /* get rid of O_NONBLOCK, keep O_DIRECT */
-                       if (type == VKD_DISK)
-                               fcntl(fd, F_SETFL, O_DIRECT);
+                       if (S_ISREG(st.st_mode)) {
+                               if (flock(fd, LOCK_EX|LOCK_NB) < 0) {
+                                       errx(1, "Disk image %s is already "
+                                               "in use\n", fname);
+                                       /* NOT REACHED */
+                               }
+                       }
 
                        info = &DiskInfo[DiskNum];
                        l = strlen(fname);