From owner-svn-src-head@FreeBSD.ORG Mon Nov 7 09:21:18 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id ACC5F1065680; Mon, 7 Nov 2011 09:21:18 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9C57C8FC12; Mon, 7 Nov 2011 09:21:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pA79LIET067277; Mon, 7 Nov 2011 09:21:18 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pA79LIUU067275; Mon, 7 Nov 2011 09:21:18 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201111070921.pA79LIUU067275@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Mon, 7 Nov 2011 09:21:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r227297 - head/usr.sbin/boot0cfg X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Nov 2011 09:21:18 -0000 Author: ae Date: Mon Nov 7 09:21:18 2011 New Revision: 227297 URL: http://svn.freebsd.org/changeset/base/227297 Log: Reorganize write_mbr() function to be able write bootcode with different ways. Improve error reporting and also fix indenting. Now we are trying to write bootcode: 1. Directly to provider (if we can open it for writing); 2. Via GEOM_PART (if it is available); 3. Via GEOM_MBR. MFC after: 2 weeks Modified: head/usr.sbin/boot0cfg/boot0cfg.c Modified: head/usr.sbin/boot0cfg/boot0cfg.c ============================================================================== --- head/usr.sbin/boot0cfg/boot0cfg.c Mon Nov 7 07:51:10 2011 (r227296) +++ head/usr.sbin/boot0cfg/boot0cfg.c Mon Nov 7 09:21:18 2011 (r227297) @@ -96,6 +96,7 @@ static const char fmt0[] = "# flag static const char fmt1[] = "%d 0x%02x %4u:%3u:%2u 0x%02x" " %4u:%3u:%2u %10u %10u\n"; +static int geom_class_available(const char *); static int read_mbr(const char *, u_int8_t **, int); static void write_mbr(const char *, int, u_int8_t *, int); static void display_mbr(u_int8_t *); @@ -337,67 +338,95 @@ read_mbr(const char *disk, u_int8_t **mb return sizeof(buf); } +static int +geom_class_available(const char *name) +{ + struct gclass *class; + struct gmesh mesh; + int error; + + error = geom_gettree(&mesh); + if (error != 0) + errc(1, error, "Cannot get GEOM tree"); + + LIST_FOREACH(class, &mesh.lg_class, lg_class) { + if (strcmp(class->lg_name, name) == 0) { + geom_deletetree(&mesh); + return (1); + } + } + + geom_deletetree(&mesh); + return (0); +} + /* * Write out the mbr to the specified file. */ static void write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) { - int fd; - ssize_t n; - const char *errmsg; - char *pname; - struct gctl_req *grq; - - fd = open(fname, O_WRONLY | flags, 0666); - if (fd != -1) { - n = write(fd, mbr, mbr_size); - close(fd); - if (n != mbr_size) - errx(1, "%s: short write", fname); - return; - } + struct gctl_req *grq; + const char *errmsg; + char *pname; + ssize_t n; + int fd; + + fd = open(fname, O_WRONLY | flags, 0666); + if (fd != -1) { + n = write(fd, mbr, mbr_size); + close(fd); + if (n != mbr_size) + errx(1, "%s: short write", fname); + return; + } - /* - * If we're called to write to a backup file, don't try to - * write through GEOM. It only generates additional errors. - */ - if (flags != 0) - return; + /* + * If we're called to write to a backup file, don't try to + * write through GEOM. + */ + if (flags != 0) + err(1, "can't open file %s to write backup", fname); + + /* Try open it read only. */ + fd = open(fname, O_RDONLY); + if (fd == -1) { + warn("error opening %s", fname); + return; + } - /* Try open it read only. */ - fd = open(fname, O_RDONLY); - if (fd == -1) { - warn("error opening %s", fname); - return; - } - pname = g_providername(fd); - if (pname == NULL) { - warn("error getting providername for %s", fname); - return; - } - grq = gctl_get_handle(); - gctl_ro_param(grq, "class", -1, "PART"); - gctl_ro_param(grq, "arg0", -1, pname); - gctl_ro_param(grq, "verb", -1, "bootcode"); - gctl_ro_param(grq, "bootcode", mbr_size, mbr); - gctl_ro_param(grq, "flags", -1, "C"); - errmsg = gctl_issue(grq); - if (errmsg == NULL) - goto out; - - grq = gctl_get_handle(); - gctl_ro_param(grq, "verb", -1, "write MBR"); - gctl_ro_param(grq, "class", -1, "MBR"); - gctl_ro_param(grq, "geom", -1, pname); - gctl_ro_param(grq, "data", mbr_size, mbr); - errmsg = gctl_issue(grq); - if (errmsg != NULL) - err(1, "write_mbr: %s", fname); - -out: - free(pname); - gctl_free(grq); + pname = g_providername(fd); + if (pname == NULL) { + warn("error getting providername for %s", fname); + return; + } + + /* First check that GEOM_PART is available */ + if (geom_class_available("PART") != 0) { + grq = gctl_get_handle(); + gctl_ro_param(grq, "class", -1, "PART"); + gctl_ro_param(grq, "arg0", -1, pname); + gctl_ro_param(grq, "verb", -1, "bootcode"); + gctl_ro_param(grq, "bootcode", mbr_size, mbr); + gctl_ro_param(grq, "flags", -1, "C"); + errmsg = gctl_issue(grq); + if (errmsg != NULL && errmsg[0] != '\0') + errx(1, "GEOM_PART: write bootcode to %s failed: %s", + fname, errmsg); + gctl_free(grq); + } else if (geom_class_available("MBR") != 0) { + grq = gctl_get_handle(); + gctl_ro_param(grq, "verb", -1, "write MBR"); + gctl_ro_param(grq, "class", -1, "MBR"); + gctl_ro_param(grq, "geom", -1, pname); + gctl_ro_param(grq, "data", mbr_size, mbr); + errmsg = gctl_issue(grq); + if (errmsg != NULL) + err(1, "GEOM_MBR: write MBR to %s failed", fname); + gctl_free(grq); + } else + errx(1, "can't write MBR to %s", fname); + free(pname); } /*