aboutsummaryrefslogtreecommitdiff
path: root/sys/boot/userboot
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2012-08-05 12:15:15 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2012-08-05 12:15:15 +0000
commit2c6f04dc0a1fc38959acb378f6d48203cd351f60 (patch)
tree501c361d26f74b81898691e07cc2c47566e5946b /sys/boot/userboot
parent9cef00000859df891c0536e2f4c4c1f527955eb0 (diff)
Notes
Diffstat (limited to 'sys/boot/userboot')
-rw-r--r--sys/boot/userboot/test/test.c26
-rw-r--r--sys/boot/userboot/userboot.h5
-rw-r--r--sys/boot/userboot/userboot/Makefile1
-rw-r--r--sys/boot/userboot/userboot/devicename.c80
-rw-r--r--sys/boot/userboot/userboot/userboot_disk.c83
5 files changed, 102 insertions, 93 deletions
diff --git a/sys/boot/userboot/test/test.c b/sys/boot/userboot/test/test.c
index a752a8032ef80..8745d315cbf51 100644
--- a/sys/boot/userboot/test/test.c
+++ b/sys/boot/userboot/test/test.c
@@ -26,6 +26,8 @@
* $FreeBSD$
*/
+#include <sys/types.h>
+#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
@@ -251,6 +253,29 @@ test_diskread(void *arg, int unit, uint64_t offset, void *dst, size_t size,
return (0);
}
+int
+test_diskioctl(void *arg, int unit, u_long cmd, void *data)
+{
+ struct stat sb;
+
+ if (unit != 0 || disk_fd == -1)
+ return (EBADF);
+ switch (cmd) {
+ case DIOCGSECTORSIZE:
+ *(u_int *)data = 512;
+ break;
+ case DIOCGMEDIASIZE:
+ if (fstat(disk_fd, &sb) == 0)
+ *(off_t *)data = sb.st_size;
+ else
+ return (ENOTTY);
+ break;
+ default:
+ return (ENOTTY);
+ };
+ return (0);
+}
+
/*
* Guest virtual machine i/o
*
@@ -353,6 +378,7 @@ struct loader_callbacks_v1 cb = {
.stat = test_stat,
.diskread = test_diskread,
+ .diskioctl = test_diskioctl,
.copyin = test_copyin,
.copyout = test_copyout,
diff --git a/sys/boot/userboot/userboot.h b/sys/boot/userboot/userboot.h
index 7d8263ee01042..9b0572e5ab007 100644
--- a/sys/boot/userboot/userboot.h
+++ b/sys/boot/userboot/userboot.h
@@ -175,4 +175,9 @@ struct loader_callbacks_v1 {
*/
void (*getmem)(void *arg, uint64_t *lowmem,
uint64_t *highmem);
+ /*
+ * ioctl interface to the disk device
+ */
+ int (*diskioctl)(void *arg, int unit, u_long cmd,
+ void *data);
};
diff --git a/sys/boot/userboot/userboot/Makefile b/sys/boot/userboot/userboot/Makefile
index 28ddc129f99cf..bc0a309827375 100644
--- a/sys/boot/userboot/userboot/Makefile
+++ b/sys/boot/userboot/userboot/Makefile
@@ -32,7 +32,6 @@ CFLAGS+= -I${.CURDIR}/../../common
CFLAGS+= -I${.CURDIR}/../../..
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
CFLAGS+= -ffreestanding -I.
-CFLAGS+= -DLOADER_GPT_SUPPORT -DLOADER_MBR_SUPPORT
LDFLAGS+= -nostdlib -Wl,-Bsymbolic
diff --git a/sys/boot/userboot/userboot/devicename.c b/sys/boot/userboot/userboot/devicename.c
index 24c5179f8593c..d54d0230d7b94 100644
--- a/sys/boot/userboot/userboot/devicename.c
+++ b/sys/boot/userboot/userboot/devicename.c
@@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
#include <stand.h>
#include <string.h>
-#include <sys/disklabel.h>
#include "bootstrap.h"
#include "disk.h"
@@ -87,7 +86,7 @@ userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **p
{
struct disk_devdesc *idev;
struct devsw *dv;
- int i, unit, slice, partition, err;
+ int i, unit, err;
char *cp;
const char *np;
@@ -113,62 +112,9 @@ userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **p
break;
case DEVT_DISK:
- unit = -1;
- slice = -1;
- partition = -1;
- if (*np && (*np != ':')) {
- unit = strtol(np, &cp, 10); /* next comes the unit number */
- if (cp == np) {
- err = EUNIT;
- goto fail;
- }
-#ifdef LOADER_GPT_SUPPORT
- if (*cp == 'p') { /* got a GPT partition */
- np = cp + 1;
- slice = strtol(np, &cp, 10);
- if (cp == np) {
- err = ESLICE;
- goto fail;
- }
- if (*cp && (*cp != ':')) {
- err = EINVAL;
- goto fail;
- }
- partition = 0xff;
- } else {
-#endif
- if (*cp == 's') { /* got a slice number */
- np = cp + 1;
- slice = strtol(np, &cp, 10);
- if (cp == np) {
- err = ESLICE;
- goto fail;
- }
- }
- if (*cp && (*cp != ':')) {
- partition = *cp - 'a'; /* got a partition number */
- if ((partition < 0) || (partition >= MAXPARTITIONS)) {
- err = EPART;
- goto fail;
- }
- cp++;
- }
-#ifdef LOADER_GPT_SUPPORT
- }
-#endif
- } else {
- cp = np;
- }
- if (*cp && (*cp != ':')) {
- err = EINVAL;
+ err = disk_parsedev(idev, np, path);
+ if (err != 0)
goto fail;
- }
-
- idev->d_unit = unit;
- idev->d_slice = slice;
- idev->d_partition = partition;
- if (path != NULL)
- *path = (*cp == 0) ? cp : cp + 1;
break;
case DEVT_CD:
@@ -219,8 +165,7 @@ userboot_fmtdev(void *vdev)
{
struct disk_devdesc *dev = (struct disk_devdesc *)vdev;
static char buf[128]; /* XXX device length constant? */
- char *cp;
-
+
switch(dev->d_type) {
case DEVT_NONE:
strcpy(buf, "(no device)");
@@ -231,22 +176,7 @@ userboot_fmtdev(void *vdev)
break;
case DEVT_DISK:
- cp = buf;
- cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit);
-#ifdef LOADER_GPT_SUPPORT
- if (dev->d_partition == 0xff) {
- cp += sprintf(cp, "p%d", dev->d_slice);
- } else {
-#endif
- if (dev->d_slice > 0)
- cp += sprintf(cp, "s%d", dev->d_slice);
- if (dev->d_partition >= 0)
- cp += sprintf(cp, "%c", dev->d_partition + 'a');
-#ifdef LOADER_GPT_SUPPORT
- }
-#endif
- strcat(cp, ":");
- break;
+ return (disk_fmtdev(vdev));
case DEVT_NET:
case DEVT_ZFS:
diff --git a/sys/boot/userboot/userboot/userboot_disk.c b/sys/boot/userboot/userboot/userboot_disk.c
index 074d3e1620be1..84c4038ee7509 100644
--- a/sys/boot/userboot/userboot/userboot_disk.c
+++ b/sys/boot/userboot/userboot/userboot_disk.c
@@ -31,23 +31,31 @@ __FBSDID("$FreeBSD$");
* Userboot disk image handling.
*/
+#include <sys/disk.h>
#include <stand.h>
-
#include <stdarg.h>
-#include <uuid.h>
-
#include <bootstrap.h>
#include "disk.h"
#include "libuserboot.h"
+struct userdisk_info {
+ uint64_t mediasize;
+ uint16_t sectorsize;
+};
+
int userboot_disk_maxunit = 0;
+static int userdisk_maxunit = 0;
+static struct userdisk_info *ud_info;
+
static int userdisk_init(void);
+static void userdisk_cleanup(void);
static int userdisk_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize);
static int userdisk_open(struct open_file *f, ...);
static int userdisk_close(struct open_file *f);
+static int userdisk_ioctl(struct open_file *f, u_long cmd, void *data);
static void userdisk_print(int verbose);
struct devsw userboot_disk = {
@@ -57,41 +65,70 @@ struct devsw userboot_disk = {
userdisk_strategy,
userdisk_open,
userdisk_close,
- noioctl,
+ userdisk_ioctl,
userdisk_print,
- NULL
+ userdisk_cleanup
};
/*
- * Nothing to do here.
+ * Initialize userdisk_info structure for each disk.
*/
static int
userdisk_init(void)
{
+ off_t mediasize;
+ u_int sectorsize;
+ int i;
+
+ userdisk_maxunit = userboot_disk_maxunit;
+ if (userdisk_maxunit > 0) {
+ ud_info = malloc(sizeof(*ud_info) * userdisk_maxunit);
+ if (ud_info == NULL)
+ return (ENOMEM);
+ for (i = 0; i < userdisk_maxunit; i++) {
+ if (CALLBACK(diskioctl, i, DIOCGSECTORSIZE,
+ &sectorsize) != 0 || CALLBACK(diskioctl, i,
+ DIOCGMEDIASIZE, &mediasize) != 0)
+ return (ENXIO);
+ ud_info[i].mediasize = mediasize;
+ ud_info[i].sectorsize = sectorsize;
+ }
+ }
return(0);
}
+static void
+userdisk_cleanup(void)
+{
+
+ if (userdisk_maxunit > 0)
+ free(ud_info);
+}
+
/*
* Print information about disks
*/
static void
userdisk_print(int verbose)
{
- int i;
- char line[80];
- struct disk_devdesc dev;
+ struct disk_devdesc dev;
+ char line[80];
+ int i;
- for (i = 0; i < userboot_disk_maxunit; i++) {
+ for (i = 0; i < userdisk_maxunit; i++) {
sprintf(line, " disk%d: Guest drive image\n", i);
pager_output(line);
dev.d_dev = &userboot_disk;
dev.d_unit = i;
dev.d_slice = -1;
dev.d_partition = -1;
- dev.d_offset = 0;
- sprintf(line, " disk%d", i);
- disk_print(&dev, line, verbose);
+ if (disk_open(&dev, ud_info[i].mediasize,
+ ud_info[i].sectorsize) == 0) {
+ sprintf(line, " disk%d", i);
+ disk_print(&dev, line, verbose);
+ disk_close(&dev);
+ }
}
}
@@ -108,17 +145,20 @@ userdisk_open(struct open_file *f, ...)
dev = va_arg(ap, struct disk_devdesc *);
va_end(ap);
- if (dev->d_unit < 0 || dev->d_unit >= userboot_disk_maxunit)
+ if (dev->d_unit < 0 || dev->d_unit >= userdisk_maxunit)
return (EIO);
- return (disk_open(dev));
+ return (disk_open(dev, ud_info[dev->d_unit].mediasize,
+ ud_info[dev->d_unit].sectorsize));
}
static int
userdisk_close(struct open_file *f)
{
+ struct disk_devdesc *dev;
- return(0);
+ dev = (struct disk_devdesc *)f->f_devdata;
+ return (disk_close(dev));
}
static int
@@ -136,7 +176,7 @@ userdisk_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
return (EINVAL);
if (rsize)
*rsize = 0;
- off = (dblk + dev->d_offset) * DISK_SECSIZE;
+ off = (dblk + dev->d_offset) * ud_info[dev->d_unit].sectorsize;
rc = CALLBACK(diskread, dev->d_unit, off, buf, size, &resid);
if (rc)
return (rc);
@@ -144,3 +184,12 @@ userdisk_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
*rsize = size - resid;
return (0);
}
+
+static int
+userdisk_ioctl(struct open_file *f, u_long cmd, void *data)
+{
+ struct disk_devdesc *dev;
+
+ dev = (struct disk_devdesc *)f->f_devdata;
+ return (CALLBACK(diskioctl, dev->d_unit, cmd, data));
+}