From patchwork Wed May 12 04:16:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 1477398 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2607:f8b0:4864:20::13e; helo=mail-il1-x13e.google.com; envelope-from=swupdate+bncbcl4hcw73qcbbrnn5wcamgqekspzjvq@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20161025 header.b=oAgcXeHI; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=GG1dAQHO; dkim-atps=neutral Received: from mail-il1-x13e.google.com (mail-il1-x13e.google.com [IPv6:2607:f8b0:4864:20::13e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fg1hq6ZNmz9sVt for ; Wed, 12 May 2021 14:17:14 +1000 (AEST) Received: by mail-il1-x13e.google.com with SMTP id l6-20020a056e021c06b02901b9680ed93esf8539280ilh.0 for ; Tue, 11 May 2021 21:17:14 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1620793029; cv=pass; d=google.com; s=arc-20160816; b=wi4GXY4eweEqfNTIcnROqyGv77+BRKSviVPEfGh3A1V6P6LLyohmw0XE9giKInot7i RViAK9snB0X+DgwyN3wzdEy3esWyxYcZbPmCn7piDEFooP8h3WyYS8P/7n8KDMbAuYm4 enmjSePXbIf9HzjnGO1gFNCaeh7NCEaQP/zFOVg/8L+DFSgBavppARshoKWW5Qa1SyE2 2dHZsJgY9K/1mVr1Y+B3c3GpZ98gQzvs7Q+KG8x38d/ClIEW0yhcIh2v7XHOskT3h4zE nYhVcTS1vMjRtCUFTo9uxej8XmX/vgun1+c4xGCJqk+1t/4KEZOy4jsFHHcH8U3sRcyN 8EPw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:mime-version:message-id:date :subject:cc:to:from:sender:dkim-signature:dkim-signature; bh=AN8Q7HHdYhXC92NvFKuSgcpPpd0LK8eeS7Kt2dOIUic=; b=GKGRUi/pndpOuyBPGwD1filj//5pgbE0H3Hj6Sk7iwaZq+02IAjaMZQSnsyzI8mIVV pPbqaovjoq6ODs1ipkTp9mAUyS5iz19c5Y0Vd2YGfyhMlKPdmdVYI8U+xU8kqjMwHFer 3ia4OIxjL1g/Y8kOZ0neg0IJkec1JPvtGxR3z64jaZ5BClGlODJfoL4+bLBHkui/FERx 9ErDt64yVFp/5uYAPbJyLrKhfX4yFcW1xfiGw9QQVb/0wp4Tm7k0AN1BGuOAMZPUD0iZ J2iYNot3nEdBSuCLXCpTyZWGI/BhuEg8xIsxTCObeyBFvACc76KiSy/0jDWqhToROi/q 0xiQ== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=MhwPEYJt; spf=pass (google.com: domain of james.hilliard1@gmail.com designates 2607:f8b0:4864:20::12b as permitted sender) smtp.mailfrom=james.hilliard1@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:mime-version :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=AN8Q7HHdYhXC92NvFKuSgcpPpd0LK8eeS7Kt2dOIUic=; b=oAgcXeHIY13zLTbtzHtAl1zDTUgXmq+ZTR+O1/Gw5+MXzR5fqVtBYlaT77ce8KUor5 JkOrtyPsPQZcjPiP5cMg7OSDjY+nCO4qenmS+RDjR2BJ2lP/RjakiTglXc46E0+Oia2k J4YsFuY8NI6m7voVYlmF7QCU2kutd9u1uUzcPsa/yjnebmfowVwZt1q1YfWr2PFDVyWH hXEafDxKI+avBJDZN0pKVL15+BGiBm7jy8VyAvockFg53axbjorF8w4LvJEewhsjvp56 ORjTtEa0UOHdDN+WrWxb4zfIVf6wyPJogTRz2hhubhu2K+O0CTKhE83/P0pKAFEBbP/e W2Wg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-subscribe:list-unsubscribe; bh=AN8Q7HHdYhXC92NvFKuSgcpPpd0LK8eeS7Kt2dOIUic=; b=GG1dAQHOyqlssyYZHWsI7AcqrjHSUJ4SuHeitx9PvXDox3v/tAmsbBQQTR+cVTeJJW JcoekKM0Y3syeB8rtZf/PnL0Km70k4kAqBRlMrgECvg0ycuN2oU66McNm684FUFaKZmv H2Wtrmq4aVLujevGMzdhi1VwUBuZdxyUheIrCB1gojbMWhP+2Wvkzg2+uv63Uz9n4kh0 8SSL3Y9z0rVU+z/jZVQ1ULCfHLASKuPtA8gSuVNW08n/fRuyW8yvTlH8DuCWNu2ldGW2 jJMzljm7lIaAhiOZc8/TaxGxAPnyI9GSc0m4iz6uyRlGGzK1mfR2lYIs/eH6jP+JPIPZ 810A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:from:to:cc:subject:date:message-id :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:list-subscribe:list-unsubscribe; bh=AN8Q7HHdYhXC92NvFKuSgcpPpd0LK8eeS7Kt2dOIUic=; b=NNJTWDIuPjDJSitZqvaqkKVm92oU3Ivxq8lNWsmmYr/ZP+Lec9H5tHvNwm50yv+am8 ZYrM6dMrrgl8On5V0ggGuXV9JKASt2AhhUtqLbqNVSbWgP53e2GDjnW6bm1JvZyy4Epe rV2lhmwMa1z5h0ND9qvn2H7SR/UdXjvGREkLnWdeziTseLYBFCGVH5ht/MOTFveG1AXA 4JezKMD7S8RYpr8w7zZ0hUlT72nRQIXpkBwrLAidtnqWsIDKefUnIyvxMrYaNiYIs1JE qhSYVWw8RgqnCNaMsZaecM6AB1BHDInqH24C//GnduQ5VLHMu0n/zLfQCySblOjq8Ddp H+7A== Sender: swupdate@googlegroups.com X-Gm-Message-State: AOAM5300SJ4Aers8pHIZlVBBo+dfRClMPCMdCVUZEtSaaE0oiWtMbhcQ qCQZifxZ+EzjauaBXw/Avc0= X-Google-Smtp-Source: ABdhPJwnZtYtDx41l0SBxGLuHsiqV1xfE/WMSSctr+a6Nk8pct/CncdknOFp2acIEBDhKjrOeiDuog== X-Received: by 2002:a92:d1c4:: with SMTP id u4mr19711025ilg.286.1620793029635; Tue, 11 May 2021 21:17:09 -0700 (PDT) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a05:6e02:4a3:: with SMTP id e3ls248784ils.5.gmail; Tue, 11 May 2021 21:17:09 -0700 (PDT) X-Received: by 2002:a92:d903:: with SMTP id s3mr3648819iln.140.1620793029100; Tue, 11 May 2021 21:17:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620793029; cv=none; d=google.com; s=arc-20160816; b=LZ9ys3ic9PpvTaKfWzBRc7lk8McU2Wt/U5tOnV8s3o+qE3fE0Ou3xGIh3DVcO/SjOm bX7TzjHsPqf93pOjwhnlmDxWhKzB+kn+h2k0v6wgfy/asPkdFvelTuZXOodI0PRuUap2 r6RPK/DfQsBeJUm7P92r/N96sVrr3u1rraqt8dhmG51STupGAZpj+3LYt1/0DGqjXrTk Ih0Xff9vqTJW+ZP5Si0NfxVVR1bi+8kxhxzlyI/jmWNIlRRWGAfibW0glCU1LTiw+PHq 1Fg8TSsta+fUct/JnZZ5IDD0gONg3lowQ9oj83+1ZGaWHxovIWJBKvsy10eFA58mzYU1 4zcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=uYhUtfBEv2L1EWqnSmqf/SOcO9/TRhtEts3qVQRUzws=; b=v21oX9yv8w2YiteZSb89fZtVyXavAgMtOjpc9Vvez+08oNLs2ogYovpXsLIDv6QwlN PfyOHH3GgUmX4zQylz7ULzer8A5uTzKE1uKmRZnlQLdqQegOSQL+dKuHh+TknFJekIkB 1s7f0GwDgZ/DstWb6RC6lJFuXzJk3Tf/4Jtf1ioPqAt1xyCzGRPu4MoU7tlH2LMBrBlj LUd0Jqb+62meDRP6s0yK8K1Yd0VXyhlgfiFcegrywIkcJRkW9N2hZ9csvZqr6lJ9imxV uaWosby6IfIXSssYb1qKBVDvXY/K80dXN52Vhp230mqwsz2owF2pM6KLrWhnGHSYYOJ6 WtSQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=MhwPEYJt; spf=pass (google.com: domain of james.hilliard1@gmail.com designates 2607:f8b0:4864:20::12b as permitted sender) smtp.mailfrom=james.hilliard1@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from mail-il1-x12b.google.com (mail-il1-x12b.google.com. [2607:f8b0:4864:20::12b]) by gmr-mx.google.com with ESMTPS id j1si2187933ilq.0.2021.05.11.21.17.09 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 11 May 2021 21:17:09 -0700 (PDT) Received-SPF: pass (google.com: domain of james.hilliard1@gmail.com designates 2607:f8b0:4864:20::12b as permitted sender) client-ip=2607:f8b0:4864:20::12b; Received: by mail-il1-x12b.google.com with SMTP id j12so19110759ils.4 for ; Tue, 11 May 2021 21:17:09 -0700 (PDT) X-Received: by 2002:a92:d1c4:: with SMTP id u4mr19710975ilg.286.1620793028424; Tue, 11 May 2021 21:17:08 -0700 (PDT) Received: from MacBook-Pro.localdomain (71-218-235-83.hlrn.qwest.net. [71.218.235.83]) by smtp.gmail.com with ESMTPSA id h14sm10456536ils.13.2021.05.11.21.17.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 May 2021 21:17:08 -0700 (PDT) From: James Hilliard To: swupdate@googlegroups.com Cc: James Hilliard Subject: [swupdate] [RFC PATCH 1/1] Add support for setting hybrid dos partition entries. Date: Tue, 11 May 2021 22:16:24 -0600 Message-Id: <20210512041624.70061-1-james.hilliard1@gmail.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Original-Sender: james.hilliard1@gmail.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=MhwPEYJt; spf=pass (google.com: domain of james.hilliard1@gmail.com designates 2607:f8b0:4864:20::12b as permitted sender) smtp.mailfrom=james.hilliard1@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , This adds the ability to set dos partition entries for gpt disks. This is mostly useful for booting on GPT disks from boards that don't natively support GPT. Config example: partition-1 = [ "size=550M", "start=2048", "name=boot", "type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B", "fstype=vfat", "dostype=0x0C" ]; Some things such as disk partition comparisons are not fully working yet. Signed-off-by: James Hilliard --- handlers/diskpart_handler.c | 208 +++++++++++++++++++++++++++++++++--- 1 file changed, 195 insertions(+), 13 deletions(-) diff --git a/handlers/diskpart_handler.c b/handlers/diskpart_handler.c index 65010c1..cefe200 100644 --- a/handlers/diskpart_handler.c +++ b/handlers/diskpart_handler.c @@ -60,7 +60,8 @@ enum partfield { PART_START, PART_TYPE, PART_NAME, - PART_FSTYPE + PART_FSTYPE, + PART_DOSTYPE }; const char *fields[] = { @@ -68,7 +69,8 @@ const char *fields[] = { [PART_START] = "start", [PART_TYPE] = "type", [PART_NAME] = "name", - [PART_FSTYPE] = "fstype" + [PART_FSTYPE] = "fstype", + [PART_DOSTYPE] = "dostype" }; struct partition_data { @@ -78,6 +80,7 @@ struct partition_data { char type[SWUPDATE_GENERAL_STRING_SIZE]; char name[SWUPDATE_GENERAL_STRING_SIZE]; char fstype[SWUPDATE_GENERAL_STRING_SIZE]; + char dostype[SWUPDATE_GENERAL_STRING_SIZE]; LIST_ENTRY(partition_data) next; }; LIST_HEAD(listparts, partition_data); @@ -101,8 +104,17 @@ struct hnd_priv { static int diskpart_set_partition(struct fdisk_partition *pa, struct partition_data *part, unsigned long sector_size, - struct fdisk_parttype *parttype) + struct fdisk_parttype *parttype, + unsigned long hybrid) { + TRACE("set partition-%zu:%s size %" PRIu64 " start %zu type %s%s%s", + part->partno != LIBFDISK_INIT_UNDEF(part->partno) ? part->partno : 0, + strlen(part->name) ? part->name : "UNDEF NAME", + part->size != LIBFDISK_INIT_UNDEF(part->size) ? part->size / sector_size : 0, + part->start!= LIBFDISK_INIT_UNDEF(part->start) ? part->start : 0, + part->type, + strlen(part->dostype) ? " dostype " : "", + strlen(part->dostype) ? part->dostype : ""); int ret = 0; if (!sector_size) @@ -114,14 +126,14 @@ static int diskpart_set_partition(struct fdisk_partition *pa, ret = fdisk_partition_set_start(pa, part->start); else ret = fdisk_partition_start_follow_default(pa, 1); - if (part->partno != LIBFDISK_INIT_UNDEF(part->partno)) + if (!hybrid && part->partno != LIBFDISK_INIT_UNDEF(part->partno)) ret |= fdisk_partition_set_partno(pa, part->partno); else ret |= fdisk_partition_partno_follow_default(pa, 1); - if (strlen(part->name)) - ret |= fdisk_partition_set_name(pa, part->name); + if (!hybrid && strlen(part->name)) + ret |= fdisk_partition_set_name(pa, part->name); if (part->size != LIBFDISK_INIT_UNDEF(part->size)) - ret |= fdisk_partition_set_size(pa, part->size / sector_size); + ret |= fdisk_partition_set_size(pa, part->size / sector_size); else ret |= fdisk_partition_end_follow_default(pa, 1); @@ -146,7 +158,7 @@ static bool diskpart_partition_cmp(const char *lbtype, struct fdisk_partition *f (strcmp(fdisk_parttype_get_string(fdisk_partition_get_type(firstpa)), fdisk_parttype_get_string(fdisk_partition_get_type(secondpa))) || strcmp(fdisk_partition_get_name(firstpa) ? fdisk_partition_get_name(firstpa) : "", - fdisk_partition_get_name(secondpa) ? fdisk_partition_get_name(secondpa) : ""))) || + fdisk_partition_get_name(secondpa) ? fdisk_partition_get_name(secondpa) : ""))) || (!strcmp(lbtype, "dos") && fdisk_parttype_get_code(fdisk_partition_get_type(firstpa)) != fdisk_parttype_get_code(fdisk_partition_get_type(secondpa))) || @@ -168,15 +180,23 @@ static int diskpart(struct img_type *img, struct dict_list *parts; struct dict_list_elem *elem; struct fdisk_context *cxt; + struct fdisk_context *doscxt = NULL; struct partition_data *part; struct partition_data *tmp; struct fdisk_table *tb = NULL; + struct fdisk_table *dostb = NULL; struct fdisk_table *oldtb = NULL; + struct fdisk_table *olddostb = NULL; struct fdisk_parttype *parttype = NULL; + struct fdisk_parttype *dosparttype = NULL; int ret = 0; unsigned long i; + unsigned long hybrid = 0; struct hnd_priv priv = {FDISK_DISKLABEL_DOS}; bool createtable = false; + bool createdostable = false; + + //fdisk_init_debug(0xffff); if (!lbtype || (strcmp(lbtype, "gpt") && strcmp(lbtype, "dos"))) { ERROR("Just GPT or DOS partition table are supported"); @@ -194,6 +214,8 @@ static int diskpart(struct img_type *img, return -ENOMEM; } + fdisk_disable_dialogs(cxt, 1); + ret = fdisk_assign_device(cxt, img->device, 0); if (ret == -EACCES) { ERROR("no access to %s", img->device); @@ -247,18 +269,31 @@ static int diskpart(struct img_type *img, case PART_FSTYPE: strncpy(part->fstype, equal, sizeof(part->fstype)); break; + case PART_DOSTYPE: + strncpy(part->dostype, equal, sizeof(part->dostype)); + hybrid++; + break; } } } elem = LIST_NEXT(elem, next); } - TRACE("partition-%zu:%s size %" PRIu64 " start %zu type %s", + if (hybrid > 3) { + ERROR("I cannot add hybrid partition %zu(%s): hybrid dos partition limit of 3 exceeded", + part->partno, strlen(part->name) ? part->name : "UNDEF NAME"); + ret = -EINVAL; + goto handler_exit; + } + + TRACE("partition-%zu:%s size %" PRIu64 " start %zu type %s%s%s", part->partno != LIBFDISK_INIT_UNDEF(part->partno) ? part->partno : 0, strlen(part->name) ? part->name : "UNDEF NAME", part->size != LIBFDISK_INIT_UNDEF(part->size) ? part->size : 0, part->start!= LIBFDISK_INIT_UNDEF(part->start) ? part->start : 0, - part->type); + part->type, + strlen(part->dostype) ? " dostype " : "", + strlen(part->dostype) ? part->dostype : ""); /* * Partitions in sw-description start from 1, @@ -287,7 +322,11 @@ static int diskpart(struct img_type *img, if (!fdisk_has_label(cxt)) { WARN("%s does not contain a recognized partition table", img->device); - fdisk_create_disklabel(cxt, lbtype); + ret = fdisk_create_disklabel(cxt, lbtype); + if (ret) { + ERROR("Failed to create disk label"); + goto handler_release; + } createtable = true; } else if (lbtype) { if (!strcmp(lbtype, "gpt")) @@ -298,12 +337,17 @@ static int diskpart(struct img_type *img, if (!fdisk_is_labeltype(cxt, priv.labeltype)) { WARN("Partition table of different type, setting to %s, all data lost !", lbtype); - fdisk_create_disklabel(cxt, lbtype); + ret = fdisk_create_disklabel(cxt, lbtype); + if (ret) { + ERROR("Failed to create disk label"); + goto handler_release; + } createtable = true; } } struct fdisk_label *lb = fdisk_get_label(cxt, NULL); + struct fdisk_label *doslb = NULL; unsigned long sector_size = fdisk_get_sector_size(cxt); /* @@ -321,6 +365,32 @@ static int diskpart(struct img_type *img, goto handler_exit; } + if (hybrid) { + doscxt = fdisk_new_nested_context(cxt, "dos"); + fdisk_disable_dialogs(doscxt, 1); + + if (!fdisk_is_labeltype(doscxt, FDISK_DISKLABEL_DOS)) { + ret = fdisk_create_disklabel(doscxt, NULL); + if (ret) { + ERROR("Failed to create hybrid disk label"); + goto handler_release; + } + createdostable = true; + } + + doslb = fdisk_get_label(doscxt, "dos"); + dostb = fdisk_new_table(); + + if (fdisk_get_partitions(doscxt, &olddostb)) + createdostable = true; + + if (!dostb) { + ERROR("OOM creating new table !"); + ret = -ENOMEM; + goto handler_exit; + } + } + i = 0; LIST_FOREACH(part, &priv.listparts, next) { @@ -334,10 +404,30 @@ static int diskpart(struct img_type *img, parttype = fdisk_label_get_parttype_from_string(lb, part->type); if (!parttype) parttype = fdisk_label_get_parttype_from_string(lb, GPT_DEFAULT_ENTRY_TYPE); + if (strlen(part->dostype)) { + struct fdisk_partition *newdospa; + newdospa = fdisk_new_partition(); + dosparttype = fdisk_label_get_parttype_from_code(doslb, ustrtoull(part->dostype, 16)); + if (!dosparttype) { + WARN("Failed to set partition type for hybrid partition: %zu(%s)", part->partno, part->name); + } + ret = diskpart_set_partition(newdospa, part, sector_size, dosparttype, hybrid); + if (ret) { + WARN("I cannot set all hybrid partition's parameters"); + } + if ((ret = fdisk_table_add_partition(dostb, newdospa)) < 0) { + ERROR("I cannot add hybrid partition %zu(%s): %d", part->partno, part->name, ret); + } + fdisk_unref_partition(newdospa); + if (ret < 0) { + fdisk_unref_partition(newpa); + goto handler_exit; + } + } } else { parttype = fdisk_label_get_parttype_from_code(lb, ustrtoull(part->type, 16)); } - ret = diskpart_set_partition(newpa, part, sector_size, parttype); + ret = diskpart_set_partition(newpa, part, sector_size, parttype, 0); if (ret) { WARN("I cannot set all partition's parameters"); } @@ -350,6 +440,31 @@ static int diskpart(struct img_type *img, i++; } + if (hybrid) { + struct fdisk_partition *newpa; + newpa = fdisk_new_partition(); + part = (struct partition_data *)calloc(1, sizeof(struct partition_data)); + if (!part) { + ERROR("FAULT: no memory"); + ret = -ENOMEM; + goto handler_exit; + } + part->start = 1; + part->size = 33 * sector_size; + dosparttype = fdisk_label_get_parttype_from_code(doslb, 0xee); + ret = diskpart_set_partition(newpa, part, sector_size, dosparttype, hybrid); + if (ret) { + WARN("I cannot set all pmbr partition's parameters"); + } + if ((ret = fdisk_table_add_partition(dostb, newpa)) < 0) { + ERROR("I cannot add the pmbr partition"); + } + fdisk_unref_partition(newpa); + if (ret < 0) + goto handler_exit; + hybrid++; + } + /* * A partiton table was found on disk, now compares the two tables * to check if they differ. @@ -387,6 +502,69 @@ static int diskpart(struct img_type *img, } } + /* + * A dos partiton table was found on disk, now compares the two tables + * to check if they differ. + */ + /* + if (hybrid && !createdostable) { + size_t numpartondisk = fdisk_table_get_nents(olddostb); + + i = hybrid; + if (numpartondisk != i) { + TRACE("Number of hybrid partitions differs on disk: %lu <--> requested: %lu", + (long unsigned int)numpartondisk, i); + createdostable = true; + } else { + struct fdisk_partition *pa, *newpa; + struct fdisk_iter *itr = fdisk_new_iter(FDISK_ITER_FORWARD); + struct fdisk_iter *olditr = fdisk_new_iter(FDISK_ITER_FORWARD); + + i = 0; + while (i < numpartondisk && !createdostable) { + newpa=NULL; + pa = NULL; + if (fdisk_table_next_partition (dostb, itr, &newpa) || + fdisk_table_next_partition (olddostb, olditr, &pa)) { + TRACE("Hybrid partition not found, something went wrong %lu !", i); + ret = -EFAULT; + goto handler_exit; + } + if (diskpart_partition_cmp("dos", pa, newpa)) { + createdostable = true; + } + + fdisk_unref_partition(newpa); + fdisk_unref_partition(pa); + i++; + } + } + } + */ + if (hybrid) { + // TODO fix dos table comparison + createdostable = true; + } + + if (createdostable) { + TRACE("Hybrid partitions on disk differ, write to disk;"); + fdisk_delete_all_partitions(doscxt); + ret = fdisk_apply_table(doscxt, dostb); + if (ret) { + ERROR("Hybrid partition table cannot be applied! %d", ret); + goto handler_exit; + } + + /* + * Everything done, write into disk + */ + ret = fdisk_write_disklabel(doscxt); + if (ret) { + ERROR("Hybrid partition table cannot be written on disk %d", ret); + goto handler_exit; + } + } + if (createtable) { TRACE("Partitions on disk differ, write to disk;"); fdisk_delete_all_partitions(cxt); @@ -412,12 +590,16 @@ static int diskpart(struct img_type *img, handler_exit: if (tb) fdisk_unref_table(tb); + if (dostb) + fdisk_unref_table(dostb); if (oldtb) fdisk_unref_table(oldtb); if (fdisk_deassign_device(cxt, 0)) WARN("Error deassign device %s", img->device); handler_release: + if (fdisk_get_parent(doscxt)) + fdisk_unref_context(doscxt); fdisk_unref_context(cxt); /*