From owner-svn-src-all@FreeBSD.ORG Tue May 12 00:30:40 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 4CD0BB25; Tue, 12 May 2015 00:30:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2EFA51387; Tue, 12 May 2015 00:30:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4C0UehX085906; Tue, 12 May 2015 00:30:40 GMT (envelope-from neel@FreeBSD.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4C0UdHR085904; Tue, 12 May 2015 00:30:39 GMT (envelope-from neel@FreeBSD.org) Message-Id: <201505120030.t4C0UdHR085904@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: neel set sender to neel@FreeBSD.org using -f From: Neel Natu Date: Tue, 12 May 2015 00:30:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282788 - head/usr.sbin/bhyve X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 May 2015 00:30:40 -0000 Author: neel Date: Tue May 12 00:30:39 2015 New Revision: 282788 URL: https://svnweb.freebsd.org/changeset/base/282788 Log: Allow configuration of the sector size advertised to the guest. The default behavior is to infer the logical and physical sector sizes from the block device backend. However older versions of Windows only work with specific logical/physical combinations: - Vista and Windows 7: 512/512 - Windows 7 SP1: 512/512 or 512/4096 For this reason allow the sector size to be specified using the following block device option: sectorsize=logical[/physical] Reported by: Leon Dang (ldang@nahannisys.com) Reviewed by: grehan MFC after: 2 weeks Modified: head/usr.sbin/bhyve/bhyve.8 head/usr.sbin/bhyve/block_if.c Modified: head/usr.sbin/bhyve/bhyve.8 ============================================================================== --- head/usr.sbin/bhyve/bhyve.8 Tue May 12 00:27:52 2015 (r282787) +++ head/usr.sbin/bhyve/bhyve.8 Tue May 12 00:30:39 2015 (r282788) @@ -193,8 +193,13 @@ format. .Pp Block storage devices: .Bl -tag -width 10n -.It Pa /filename Ns Oo , Ns Li nocache Oc Ns Oo , Ns Li direct Oc Ns Oo , Ns Li ro Oc -.It Pa /dev/xxx Ns Oo , Ns Ar nocache Oc Ns Oo , Ns Ar direct Oc Ns Oo , Ns Ar ro Oc +.It Pa /filename Ns Oo , Ns Ar block-device-options Oc +.It Pa /dev/xxx Ns Oo , Ns Ar block-device-options Oc +.El +.Pp +The +.Ar block-device-options +are: .Bl -tag -width 8n .It Li nocache Open the file with @@ -204,14 +209,10 @@ Open the file using .Dv O_SYNC . .It Li ro Force the file to be opened read-only. -.El -.Pp -The -.Li nocache , -.Li direct , -and -.Li ro -options are not available for virtio block devices. +.It Li sectorsize= Ns Ar logical Ns Oo / Ns Ar physical Oc +Specify the logical and physical sector sizes of the emulated disk. +The physical sector size is optional and is equal to the logical sector size +if not explicitly specified. .El .Pp TTY devices: Modified: head/usr.sbin/bhyve/block_if.c ============================================================================== --- head/usr.sbin/bhyve/block_if.c Tue May 12 00:27:52 2015 (r282787) +++ head/usr.sbin/bhyve/block_if.c Tue May 12 00:30:39 2015 (r282788) @@ -392,16 +392,18 @@ blockif_open(const char *optstr, const c { char tname[MAXCOMLEN + 1]; char name[MAXPATHLEN]; - char *nopt, *xopts; + char *nopt, *xopts, *cp; struct blockif_ctxt *bc; struct stat sbuf; struct diocgattr_arg arg; off_t size, psectsz, psectoff; int extra, fd, i, sectsz; - int nocache, sync, ro, candelete, geom; + int nocache, sync, ro, candelete, geom, ssopt, pssopt; pthread_once(&blockif_once, blockif_init); + fd = -1; + ssopt = 0; nocache = 0; sync = 0; ro = 0; @@ -410,16 +412,25 @@ blockif_open(const char *optstr, const c * The first element in the optstring is always a pathname. * Optional elements follow */ - nopt = strdup(optstr); - for (xopts = strtok(nopt, ","); - xopts != NULL; - xopts = strtok(NULL, ",")) { - if (!strcmp(xopts, "nocache")) + nopt = xopts = strdup(optstr); + while (xopts != NULL) { + cp = strsep(&xopts, ","); + if (cp == nopt) /* file or device pathname */ + continue; + else if (!strcmp(cp, "nocache")) nocache = 1; - else if (!strcmp(xopts, "sync")) + else if (!strcmp(cp, "sync") || !strcmp(cp, "direct")) sync = 1; - else if (!strcmp(xopts, "ro")) + else if (!strcmp(cp, "ro")) ro = 1; + else if (sscanf(cp, "sectorsize=%d/%d", &ssopt, &pssopt) == 2) + ; + else if (sscanf(cp, "sectorsize=%d", &ssopt) == 1) + pssopt = ssopt; + else { + fprintf(stderr, "Invalid device option \"%s\"\n", cp); + goto err; + } } extra = 0; @@ -437,13 +448,12 @@ blockif_open(const char *optstr, const c if (fd < 0) { perror("Could not open backing file"); - return (NULL); + goto err; } if (fstat(fd, &sbuf) < 0) { perror("Could not stat backing file"); - close(fd); - return (NULL); + goto err; } /* @@ -457,8 +467,7 @@ blockif_open(const char *optstr, const c if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 || ioctl(fd, DIOCGSECTORSIZE, §sz)) { perror("Could not fetch dev blk/sector size"); - close(fd); - return (NULL); + goto err; } assert(size != 0); assert(sectsz != 0); @@ -473,10 +482,39 @@ blockif_open(const char *optstr, const c } else psectsz = sbuf.st_blksize; + if (ssopt != 0) { + if (!powerof2(ssopt) || !powerof2(pssopt) || ssopt < 512 || + ssopt > pssopt) { + fprintf(stderr, "Invalid sector size %d/%d\n", + ssopt, pssopt); + goto err; + } + + /* + * Some backend drivers (e.g. cd0, ada0) require that the I/O + * size be a multiple of the device's sector size. + * + * Validate that the emulated sector size complies with this + * requirement. + */ + if (S_ISCHR(sbuf.st_mode)) { + if (ssopt < sectsz || (ssopt % sectsz) != 0) { + fprintf(stderr, "Sector size %d incompatible " + "with underlying device sector size %d\n", + ssopt, sectsz); + goto err; + } + } + + sectsz = ssopt; + psectsz = pssopt; + psectoff = 0; + } + bc = calloc(1, sizeof(struct blockif_ctxt)); if (bc == NULL) { - close(fd); - return (NULL); + perror("calloc"); + goto err; } bc->bc_magic = BLOCKIF_SIG; @@ -506,6 +544,10 @@ blockif_open(const char *optstr, const c } return (bc); +err: + if (fd >= 0) + close(fd); + return (NULL); } static int