From: Vojtech Trefny Date: Wed, 25 Feb 2026 13:18:42 +0000 (+0100) Subject: libblkid: Add support for DASD partition table X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=c408b657283fdedcdf3d4961c007805077b72bc9;p=thirdparty%2Futil-linux.git libblkid: Add support for DASD partition table Signed-off-by: Vojtech Trefny --- diff --git a/include/Makemodule.am b/include/Makemodule.am index 143677c8b9..3bc77ad6e7 100644 --- a/include/Makemodule.am +++ b/include/Makemodule.am @@ -61,6 +61,7 @@ dist_noinst_HEADERS += \ include/plymouth-ctrl.h \ include/procfs.h \ include/pt-bsd.h \ + include/pt-dasd.h \ include/pt-mbr.h \ include/pt-mbr-partnames.h \ include/pt-gpt-partnames.h \ diff --git a/include/pt-dasd.h b/include/pt-dasd.h new file mode 100644 index 0000000000..fa0f63bd30 --- /dev/null +++ b/include/pt-dasd.h @@ -0,0 +1,229 @@ +/* + * No copyright is claimed. This code is in the public domain; do with + * it what you wish. + */ +#ifndef UTIL_LINUX_PT_DASD_H +#define UTIL_LINUX_PT_DASD_H + +#include +#include "bitops.h" + +#define DASD_MAX_PARTITIONS 3 + +#define DASD_VOL1_MAGIC "\xe5\xd6\xd3\xf1" /* "VOL1" in EBCDIC */ +#define DASD_LNX1_MAGIC "\xd3\xd5\xe7\xf1" /* "LNX1" in EBCDIC */ +#define DASD_CMS1_MAGIC "\xc3\xd4\xe2\xf1" /* "CMS1" in EBCDIC */ + +#define DASD_FMT_ID_F1 0xf1 +#define DASD_FMT_ID_F4 0xf4 +#define DASD_FMT_ID_F5 0xf5 +#define DASD_FMT_ID_F7 0xf7 +#define DASD_FMT_ID_F8 0xf8 +#define DASD_FMT_ID_F9 0xf9 + +/* Large volume compatibility cylinder threshold */ +#define DASD_LV_COMPAT_CYL 0xFFFE + +#define DASD_VOLSER_LENGTH 6 + +/* Format 4 key field: 44 bytes of 0x04 */ +#define DASD_F4_KEYCD_BYTE 0x04 +#define DASD_F4_KEYCD_LENGTH 44 + +struct dasd_cchhb { + uint16_t cc; + uint16_t hh; + uint8_t b; +} __attribute__ ((packed)); + +struct dasd_cchh { + uint16_t cc; + uint16_t hh; +} __attribute__ ((packed)); + +struct dasd_extent { + uint8_t typeind; + uint8_t seqno; + struct dasd_cchh llimit; + struct dasd_cchh ulimit; +} __attribute__ ((packed)); + +/* + * CDL Volume Label. + */ +struct dasd_volume_label_cdl { + char volkey[4]; /* record key*/ + char vollbl[4]; /* "VOL1" in EBCDIC */ + char volid[6]; /* volume identifier (VOLSER) */ + uint8_t security; + struct dasd_cchhb vtoc; /* VTOC address */ + char res1[5]; + char cisize[4]; + char blkperci[4]; + char labperci[4]; + char res2[4]; + char lvtoc[14]; + char res3[29]; +} __attribute__ ((packed)); + +/* + * LDL Volume Label. + */ +struct dasd_volume_label_ldl { + char vollbl[4]; /* "LNX1" or "CMS1" in EBCDIC */ + char volid[6]; /* volume identifier (VOLSER) */ + char res1[69]; + char ldl_version; + uint64_t formatted_blocks; /* for ldl_version 0xf2 */ +} __attribute__ ((packed)); + +/* + * Format 1 / Format 8 DSCB (partition description) + */ +struct dasd_format1_label { + char DS1DSNAM[44]; /* data set name (EBCDIC) */ + uint8_t DS1FMTID; /* format identifier (0xf1 or 0xf8) */ + unsigned char DS1DSSN[6]; + uint16_t DS1VOLSQ; + uint8_t DS1CREDT[3]; + uint8_t DS1EXPDT[3]; + uint8_t DS1NOEPV; + uint8_t DS1NOBDB; + uint8_t DS1FLAG1; + unsigned char DS1SYSCD[13]; + uint8_t DS1REFD[3]; + uint8_t DS1SMSFG; + uint8_t DS1SCXTF; + uint16_t DS1SCXTV; + uint8_t DS1DSRG1; + uint8_t DS1DSRG2; + uint8_t DS1RECFM; + uint8_t DS1OPTCD; + uint16_t DS1BLKL; + uint16_t DS1LRECL; + uint8_t DS1KEYL; + uint16_t DS1RKP; + uint8_t DS1DSIND; + uint8_t DS1SCAL1; + char DS1SCAL3[3]; + uint8_t DS1LSTAR[3]; + uint16_t DS1TRBAL; + uint16_t res1; + struct dasd_extent DS1EXT1; + struct dasd_extent DS1EXT2; + struct dasd_extent DS1EXT3; + struct dasd_cchhb DS1PTRDS; +} __attribute__ ((packed)); + +/* + * Format 4 DSCB (VTOC header with geometry information) + */ +struct dasd_format4_label { + char DS4KEYCD[44]; /* key: 44 bytes of 0x04 */ + uint8_t DS4IDFMT; /* format identifier (0xf4) */ + struct dasd_cchhb DS4HPCHR; + uint16_t DS4DSREC; + struct dasd_cchh DS4HCCHH; + uint16_t DS4NOATK; + uint8_t DS4VTOCI; + uint8_t DS4NOEXT; + uint8_t DS4SMSFG; + uint8_t DS4DEVAC; + uint16_t DS4DSCYL; /* number of logical cylinders */ + uint16_t DS4DSTRK; /* number of tracks per cylinder */ + uint16_t DS4DEVTK; /* device track length */ + uint8_t DS4DEVI; + uint8_t DS4DEVL; + uint8_t DS4DEVK; + uint8_t DS4DEVFG; + uint16_t DS4DEVTL; + uint8_t DS4DEVDT; + uint8_t DS4DEVDB; + char DS4AMTIM[8]; + char DS4AMCAT[3]; + char DS4R2TIM[8]; + char res1[5]; + char DS4F6PTR[5]; + struct dasd_extent DS4VTOCE; + char res2[10]; + uint8_t DS4EFLVL; + struct dasd_cchhb DS4EFPTR; + char res3; + uint32_t DS4DCYL; /* number of logical cylinders (large volumes) */ + char res4[2]; + uint8_t DS4DEVF2; + char res5; +} __attribute__ ((packed)); + +/* + * EBCDIC to ASCII conversion table. + */ +static const unsigned char dasd_ebcdic_to_ascii[256] __attribute__((unused)) = +{ +/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ + 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, +/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ + 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC */ + 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, +/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB */ + 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC */ + 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, +/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL */ + 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, +/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ + 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, +/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ + 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, +/* 0x40 SP RSP */ + 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, +/* 0x48 . < ( + | */ + 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, +/* 0x50 & */ + 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, +/* 0x58 ~ ! $ * ) ; */ + 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, +/* 0x60 - / */ + 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, +/* 0x68 ---- , % _ > ? */ + 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, +/* 0x70 --- */ + 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* 0x78 * ` : # @ ' = " */ + 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, +/* 0x80 * a b c d e f g */ + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +/* 0x88 h i */ + 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, +/* 0x90 j k l m n o p */ + 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +/* 0x98 q r */ + 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, +/* 0xA0 ~ s t u v w x */ + 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, +/* 0xA8 y z */ + 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, +/* 0xB0 ^ */ + 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, +/* 0xB8 ---- [ ] */ + 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, +/* 0xC0 { A B C D E F G */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +/* 0xC8 H I */ + 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, +/* 0xD0 } J K L M N O P */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, +/* 0xD8 Q R */ + 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, +/* 0xE0 \ */ + 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, +/* 0xE8 Y Z */ + 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, +/* 0xF0 0 1 2 3 4 5 6 7 */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +/* 0xF8 8 9 */ + 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 +}; + +#endif /* UTIL_LINUX_PT_DASD_H */ diff --git a/libblkid/meson.build b/libblkid/meson.build index 2435692cd2..4c07b7a1e6 100644 --- a/libblkid/meson.build +++ b/libblkid/meson.build @@ -40,6 +40,7 @@ lib_blkid_sources = ''' src/partitions/aix.h src/partitions/atari.c src/partitions/bsd.c + src/partitions/dasd.c src/partitions/dos.c src/partitions/gpt.c src/partitions/mac.c diff --git a/libblkid/src/Makemodule.am b/libblkid/src/Makemodule.am index ce65d50294..5a8d1d702f 100644 --- a/libblkid/src/Makemodule.am +++ b/libblkid/src/Makemodule.am @@ -30,6 +30,7 @@ libblkid_la_SOURCES = \ libblkid/src/partitions/aix.h \ libblkid/src/partitions/atari.c \ libblkid/src/partitions/bsd.c \ + libblkid/src/partitions/dasd.c \ libblkid/src/partitions/dos.c \ libblkid/src/partitions/gpt.c \ libblkid/src/partitions/mac.c \ diff --git a/libblkid/src/partitions/dasd.c b/libblkid/src/partitions/dasd.c new file mode 100644 index 0000000000..501a603f76 --- /dev/null +++ b/libblkid/src/partitions/dasd.c @@ -0,0 +1,385 @@ +/* + * DASD partition table probing + * + * Copyright (C) 2026 Red Hat, Inc. + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * Inspired by fdasd (s390-tools), Linux kernel and libparted. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "pt-dasd.h" +#include "partitions.h" + +static void dasd_get_volser(const char *volid, char *volser) +{ + int i = 0; + + for (i = 0; i < DASD_VOLSER_LENGTH; i++) + volser[i] = dasd_ebcdic_to_ascii[(unsigned char) volid[i]]; + volser[DASD_VOLSER_LENGTH] = '\0'; + + /* trim trailing spaces */ + for (i = DASD_VOLSER_LENGTH - 1; volser[i] == ' '; i--) + volser[i] = '\0'; +} + +static void dasd_get_dsnam(const struct dasd_format1_label *f1, char *dsnam) +{ + size_t i = 0; + + for (i = 0; i < sizeof(f1->DS1DSNAM); i++) + dsnam[i] = dasd_ebcdic_to_ascii[(unsigned char) f1->DS1DSNAM[i]]; + dsnam[sizeof(f1->DS1DSNAM)] = '\0'; + + /* trim trailing spaces */ + for (i = sizeof(f1->DS1DSNAM) - 1; i != 0 && dsnam[i] == ' '; i--) + dsnam[i] = '\0'; +} + +/* + * CCHH for large volumes: + * - upper 12 bits of hh hold the upper cylinder bits + * - lower 4 bits of hh are the head number + */ +static uint32_t dasd_cchh_get_cc(const struct dasd_cchh *p) +{ + uint32_t cyl; + + cyl = be16_to_cpu(p->hh) & 0xFFF0; + cyl <<= 12; + cyl |= be16_to_cpu(p->cc); + return cyl; +} + +static uint16_t dasd_cchh_get_hh(const struct dasd_cchh *p) +{ + return be16_to_cpu(p->hh) & 0x000F; +} + +static bool is_dasd_cdl_label(const unsigned char *buf) +{ + return memcmp(buf + 4, DASD_VOL1_MAGIC, 4) == 0; +} + +static bool is_dasd_ldl_label(const unsigned char *buf) +{ + return memcmp(buf, DASD_LNX1_MAGIC, 4) == 0 || + memcmp(buf, DASD_CMS1_MAGIC, 4) == 0; +} + +/* + * Format 4: 44-byte key field filled with 0x04 + DS4IDFMT (0xf4) + */ +static bool is_dasd_f4_label(const unsigned char *buf) +{ + int i = 0; + + for (i = 0; i < DASD_F4_KEYCD_LENGTH; i++) { + if (buf[i] != DASD_F4_KEYCD_BYTE) + return false; + } + if (buf[DASD_F4_KEYCD_LENGTH] != DASD_FMT_ID_F4) + return false; + + return true; +} + +/* + * CDL -- up to three partitions defined by the F1/8 labels + */ +static int probe_dasd_pt_cdl(blkid_probe pr, blkid_partlist ls, + blkid_parttable tab, + unsigned int blocksize) +{ + const struct dasd_format4_label *f4; + const struct dasd_format1_label *f1; + const unsigned char *buf; + unsigned int blk_per_trk = 0; + uint16_t heads; + uint32_t cylinders; + unsigned int blk; + int partno = 0; + + /* + * Looking for Format 4 label at blocks 3-20. + * On a real DASD, it is at CC=0 HH=1 R=1, which maps to + * linux block = blk_per_trk (one track after the start), + * but we don't know blk_per_trk yet. + */ + for (blk = 3; blk <= 20; blk++) { + buf = blkid_probe_get_buffer(pr, + (uint64_t) blk * blocksize, + sizeof(struct dasd_format4_label)); + if (!buf) + return errno ? -errno : BLKID_PROBE_NONE; + if (is_dasd_f4_label(buf)) { + blk_per_trk = blk; + break; + } + } + + if (!blk_per_trk) { + DBG(LOWPROBE, ul_debug("DASD: CDL detected but no F4 label found")); + return BLKID_PROBE_NONE; + } + + f4 = (const struct dasd_format4_label *) buf; + + heads = be16_to_cpu(f4->DS4DSTRK); + if (heads == 0) + return BLKID_PROBE_NONE; + + cylinders = be16_to_cpu(f4->DS4DSCYL); + + /* large volume -> use DS4DCYL */ + if (cylinders == DASD_LV_COMPAT_CYL) + cylinders = be32_to_cpu(f4->DS4DCYL); + + DBG(LOWPROBE, ul_debug("DASD CDL: blk_per_trk=%u heads=%u cylinders=%u blocksize=%u", + blk_per_trk, heads, cylinders, blocksize)); + + /* scan for format 1 and format 8 labels describing the partitions */ + for (blk = blk_per_trk + 1; blk < blk_per_trk + 20 && partno < DASD_MAX_PARTITIONS; blk++) { + char dsnam[sizeof(f1->DS1DSNAM) + 1]; + char *last_dot; + size_t namelen; + uint32_t start_cc, end_cc; + uint16_t start_hh, end_hh; + uint64_t start_trk, end_trk; + uint64_t start_512, size_512; + blkid_partition par; + + buf = blkid_probe_get_buffer(pr, + (uint64_t) blk * blocksize, + sizeof(struct dasd_format1_label)); + if (!buf) + return errno ? -errno : BLKID_PROBE_NONE; + + f1 = (const struct dasd_format1_label *) buf; + + /* only format 1 and 8 are valid partition descriptors */ + if (f1->DS1FMTID != DASD_FMT_ID_F1 && f1->DS1FMTID != DASD_FMT_ID_F8) + continue; + + if (cylinders > DASD_LV_COMPAT_CYL) { + /* large volume encoding */ + start_cc = dasd_cchh_get_cc(&f1->DS1EXT1.llimit); + start_hh = dasd_cchh_get_hh(&f1->DS1EXT1.llimit); + end_cc = dasd_cchh_get_cc(&f1->DS1EXT1.ulimit); + end_hh = dasd_cchh_get_hh(&f1->DS1EXT1.ulimit); + } else { + start_cc = be16_to_cpu(f1->DS1EXT1.llimit.cc); + start_hh = be16_to_cpu(f1->DS1EXT1.llimit.hh); + end_cc = be16_to_cpu(f1->DS1EXT1.ulimit.cc); + end_hh = be16_to_cpu(f1->DS1EXT1.ulimit.hh); + } + + start_trk = (uint64_t) start_cc * heads + start_hh; + end_trk = (uint64_t) end_cc * heads + end_hh; + + if (end_trk <= start_trk) + return BLKID_PROBE_NONE; + + /* convert to 512 sectors */ + start_512 = start_trk * blk_per_trk * blocksize / 512; + size_512 = (end_trk - start_trk + 1) * blk_per_trk * blocksize / 512; + + DBG(LOWPROBE, ul_debug("DASD CDL part%d: CC=%u-%u HH=%u-%u " + "trk=%"PRIu64"-%"PRIu64" start=%"PRIu64" size=%"PRIu64, + partno + 1, start_cc, end_cc, start_hh, end_hh, + start_trk, end_trk, start_512, size_512)); + + par = blkid_partlist_add_partition(ls, tab, start_512, size_512); + if (!par) + return -ENOMEM; + + dasd_get_dsnam(f1, dsnam); + + /* split dsnam into name and type at the last '.' */ + last_dot = strrchr(dsnam, '.'); + if (last_dot) { + namelen = min((size_t)(last_dot - dsnam), sizeof(dsnam) - 1); + blkid_partition_set_name(par, (unsigned char *) dsnam, namelen); + blkid_partition_set_type_string(par, (unsigned char *) last_dot + 1, + strlen(last_dot + 1)); + } else { + blkid_partition_set_type_string(par, (unsigned char *) dsnam, + strlen(dsnam)); + } + + partno++; + } + + return BLKID_PROBE_OK; +} + +/* + * LDL -- single implicit partition starting at block 3 + */ +static int probe_dasd_pt_ldl(blkid_probe pr, blkid_partlist ls, + blkid_parttable tab, + const struct dasd_volume_label_ldl *vlabel, + unsigned int blocksize) +{ + uint64_t start_512, size_512; + uint64_t blocks; + blkid_partition par; + + start_512 = (uint64_t) 3 * blocksize / 512; + + if ((unsigned char) vlabel->ldl_version >= 0xf2) { + blocks = be64_to_cpu(vlabel->formatted_blocks); + if (blocks <= 3) { + DBG(LOWPROBE, ul_debug("DASD LDL: invalid formatted_blocks %"PRIu64, blocks)); + return BLKID_PROBE_NONE; + } + size_512 = (blocks - 3) * blocksize / 512; + } else { + size_512 = blkid_probe_get_size(pr) / 512 - start_512; + } + + DBG(LOWPROBE, ul_debug("DASD LDL: start=%"PRIu64" size=%"PRIu64" blocksize=%u", + start_512, size_512, blocksize)); + + par = blkid_partlist_add_partition(ls, tab, start_512, size_512); + if (!par) + return -ENOMEM; + + return BLKID_PROBE_OK; +} + +static const unsigned int dasd_blocksizes[] = { 4096, 2048, 1024, 512 }; + +static int probe_dasd_pt(blkid_probe pr, + const struct blkid_idmag *mag __attribute__((__unused__))) +{ + const unsigned char *buf; + blkid_parttable tab = NULL; + blkid_partlist ls; + char volser[DASD_VOLSER_LENGTH + 1]; + unsigned int blocksize; + bool is_cdl = false; + bool is_ldl = false; + const struct dasd_volume_label_cdl *cdl = NULL; + const struct dasd_volume_label_ldl *ldl = NULL; + const char *magic; + int rc; + size_t i = 0; + + blocksize = blkid_probe_get_sectorsize(pr); + buf = blkid_probe_get_buffer(pr, + (uint64_t) 2 * blocksize, + sizeof(struct dasd_volume_label_ldl)); + if (!buf) + return errno ? -errno : BLKID_PROBE_NONE; + + /* CDL -- "VOL1" at byte 4 */ + if (is_dasd_cdl_label(buf)) + is_cdl = true; + /* LDL -- "LNX1" or "CMS1" at byte 0 */ + else if (is_dasd_ldl_label(buf)) + is_ldl = true; + + /* + * check the other known DASD block sizes as well in case we are + * scanning e.g. 512 disk image + */ + if (!is_cdl && !is_ldl) { + for (i = 0; i < ARRAY_SIZE(dasd_blocksizes); i++) { + if (dasd_blocksizes[i] == blocksize) + continue; + + buf = blkid_probe_get_buffer(pr, + (uint64_t) 2 * dasd_blocksizes[i], + sizeof(struct dasd_volume_label_ldl)); + if (!buf) { + if (errno) + return -errno; + continue; + } + + if (is_dasd_cdl_label(buf)) { + is_cdl = true; + blocksize = dasd_blocksizes[i]; + break; + } + if (is_dasd_ldl_label(buf)) { + is_ldl = true; + blocksize = dasd_blocksizes[i]; + break; + } + } + } + + if (!is_cdl && !is_ldl) + return BLKID_PROBE_NONE; + + DBG(LOWPROBE, ul_debug("DASD: %s label detected (blocksize=%u)", + is_cdl ? "CDL" : "LDL", blocksize)); + + if (is_cdl) { + cdl = (const struct dasd_volume_label_cdl *) buf; + + if (blkid_probe_set_magic(pr, + (uint64_t) 2 * blocksize + + offsetof(struct dasd_volume_label_cdl, vollbl), + 4, (const unsigned char *) DASD_VOL1_MAGIC)) + return BLKID_PROBE_NONE; + + dasd_get_volser(cdl->volid, volser); + } else { + ldl = (const struct dasd_volume_label_ldl *) buf; + magic = memcmp(buf, DASD_LNX1_MAGIC, 4) == 0 ? DASD_LNX1_MAGIC : DASD_CMS1_MAGIC; + + if (blkid_probe_set_magic(pr, + (uint64_t) 2 * blocksize + + offsetof(struct dasd_volume_label_ldl, vollbl), + 4, (const unsigned char *) magic)) + return BLKID_PROBE_NONE; + + dasd_get_volser(ldl->volid, volser); + } + + blkid_partitions_strcpy_ptuuid(pr, volser); + + if (blkid_partitions_need_typeonly(pr)) + return BLKID_PROBE_OK; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + return BLKID_PROBE_NONE; + + tab = blkid_partlist_new_parttable(ls, "dasd", 0); + if (!tab) + return -ENOMEM; + + blkid_parttable_set_id(tab, (unsigned char *) volser); + + if (is_cdl) + rc = probe_dasd_pt_cdl(pr, ls, tab, blocksize); + else + rc = probe_dasd_pt_ldl(pr, ls, tab, ldl, blocksize); + + return rc; +} + +const struct blkid_idinfo dasd_pt_idinfo = +{ + .name = "dasd", + .probefunc = probe_dasd_pt, + + /* + * magic location unfortunately depends on the device geometry and + * DASD version and format (CDL or LDL) + */ + .magics = BLKID_NONE_MAGIC +}; diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c index e838b3db1f..29897f17c1 100644 --- a/libblkid/src/partitions/partitions.c +++ b/libblkid/src/partitions/partitions.c @@ -136,7 +136,8 @@ static const struct blkid_idinfo *idinfos[] = &unixware_pt_idinfo, &solaris_x86_pt_idinfo, &minix_pt_idinfo, - &atari_pt_idinfo + &atari_pt_idinfo, + &dasd_pt_idinfo, }; /* diff --git a/libblkid/src/partitions/partitions.h b/libblkid/src/partitions/partitions.h index 784e0c0e33..c6f881b6da 100644 --- a/libblkid/src/partitions/partitions.h +++ b/libblkid/src/partitions/partitions.h @@ -70,5 +70,6 @@ extern const struct blkid_idinfo gpt_pt_idinfo; extern const struct blkid_idinfo pmbr_pt_idinfo; extern const struct blkid_idinfo ultrix_pt_idinfo; extern const struct blkid_idinfo atari_pt_idinfo; +extern const struct blkid_idinfo dasd_pt_idinfo; #endif /* BLKID_PARTITIONS_H */ diff --git a/tests/expected/blkid/lowprobe-pt-dasd-cdl b/tests/expected/blkid/lowprobe-pt-dasd-cdl new file mode 100644 index 0000000000..02fa407bd5 --- /dev/null +++ b/tests/expected/blkid/lowprobe-pt-dasd-cdl @@ -0,0 +1,4 @@ +size: 20971520, sector size: 512, PT: dasd, offset: 0, id=0X3726 +--- +#1: 192 4032 0x0 name='LINUX.V0X3726.PART0001' type='NATIVE' +#2: 4224 4032 0x0 name='LINUX.V0X3726.PART0002' type='NATIVE' diff --git a/tests/expected/blkid/lowprobe-pt-dasd-ldl b/tests/expected/blkid/lowprobe-pt-dasd-ldl new file mode 100644 index 0000000000..c534d247a1 --- /dev/null +++ b/tests/expected/blkid/lowprobe-pt-dasd-ldl @@ -0,0 +1,3 @@ +size: 20971520, sector size: 512, PT: dasd, offset: 0, id=0X3526 +--- +#1: 24 14424456 0x0 diff --git a/tests/expected/partx/partx-image-dasd-cdl b/tests/expected/partx/partx-image-dasd-cdl new file mode 100644 index 0000000000..efeec668fe --- /dev/null +++ b/tests/expected/partx/partx-image-dasd-cdl @@ -0,0 +1,3 @@ +NR START END SECTORS SIZE NAME UUID + 1 192 4223 4032 2M LINUX.V0X3726.PART0001 + 2 4224 8255 4032 2M LINUX.V0X3726.PART0002 diff --git a/tests/expected/partx/partx-image-dasd-ldl b/tests/expected/partx/partx-image-dasd-ldl new file mode 100644 index 0000000000..465c5f5236 --- /dev/null +++ b/tests/expected/partx/partx-image-dasd-ldl @@ -0,0 +1,2 @@ +NR START END SECTORS SIZE NAME UUID + 1 24 14424479 14424456 6.9G diff --git a/tests/ts/blkid/images-pt/dasd-cdl.img.xz b/tests/ts/blkid/images-pt/dasd-cdl.img.xz new file mode 100644 index 0000000000..8cb11523e2 Binary files /dev/null and b/tests/ts/blkid/images-pt/dasd-cdl.img.xz differ diff --git a/tests/ts/blkid/images-pt/dasd-ldl.img.xz b/tests/ts/blkid/images-pt/dasd-ldl.img.xz new file mode 100644 index 0000000000..8fdcaabeec Binary files /dev/null and b/tests/ts/blkid/images-pt/dasd-ldl.img.xz differ