All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: christophe.varoqui@free.fr
Cc: device-mapper development <dm-devel@redhat.com>
Subject: [kpartx] Resend: add support for S/390 DASD
Date: Fri, 09 Dec 2005 12:48:23 +0100	[thread overview]
Message-ID: <43996F07.2090206@suse.de> (raw)
In-Reply-To: <1133995475.5650.54.camel@zezette>

[-- Attachment #1: Type: text/plain, Size: 625 bytes --]

Christophe Varoqui wrote:
> On mer, 2005-12-07 at 15:08 +0100, Hannes Reinecke wrote:
>> Hi Christophe,
>>
>> this patch adds kpartx support for S/390 DASD partitions.
>> Helpful when using multipath-tools on them.
>>
> Looks promising.
> 
> Can you split the fix [1] from the rest and include the dasd.c you seem
> to have left out.
> 
Errm. Of course.
Here is it.

The fix [1] is already sent (check for 'fix mapname length').

Cheers,

Hannes
-- 
Dr. Hannes Reinecke			hare@suse.de
SuSE Linux Products GmbH		S390 & zSeries
Maxfeldstraße 5				+49 911 74053 688
90409 Nürnberg				http://www.suse.de

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: kpartx-dasd-support.patch --]
[-- Type: text/x-patch; name="kpartx-dasd-support.patch", Size: 21415 bytes --]

[kpartx] Add suport for S/390 ECKD DASD

This patch adds support for S/390 ECKD DASD partition tables.

Signed-off-by: Hannes Reinecke <hare@suse.de>

diff --git a/kpartx/Makefile b/kpartx/Makefile
--- a/kpartx/Makefile
+++ b/kpartx/Makefile
@@ -10,11 +10,11 @@ CFLAGS = -pipe -g -Wall -Wunused -Wstric
 
 ifeq ($(strip $(BUILD)),klibc)
 	OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o gpt.o crc32.o \
-	       lopart.o xstrncpy.o devmapper.o \
+	       lopart.o xstrncpy.o devmapper.o dasd.o \
 	       $(MULTIPATHLIB)-$(BUILD).a $(libdm)
 else
 	LDFLAGS = -ldevmapper
-	OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o \
+	OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o \
 	       gpt.o crc32.o lopart.o xstrncpy.o devmapper.o
 endif
 
diff --git a/kpartx/dasd.c b/kpartx/dasd.c
new file mode 100644
--- /dev/null
+++ b/kpartx/dasd.c
@@ -0,0 +1,240 @@
+/*
+ * dasd.c
+ *
+ * IBM DASD partition table handling.
+ *
+ * Mostly taken from drivers/s390/block/dasd.c
+ *
+ * Copyright (c) 2005, Hannes Reinecke, SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/hdreg.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <libdevmapper.h>
+#include "devmapper.h"
+#include "kpartx.h"
+#include "byteorder.h"
+#include "dasd.h"
+
+/*
+ */
+int 
+read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
+{
+	int retval = -1;
+	int blocksize, offset, size;
+	long disksize;
+	dasd_information_t info;
+	struct hd_geometry geo;
+	char type[5] = {0,};
+	char name[7] = {0,};
+	char *label_raw;
+	volume_label_t vlabel;
+	unsigned char *data = NULL;
+	unsigned int blk;
+	int fd_dasd = -1;
+	struct stat sbuf;
+	dev_t dev;
+	char *devname;
+	char pathname[256];
+
+	if (fd < 0) {
+		return -1;
+	}
+
+	if (fstat(fd, &sbuf) == -1) {
+		return -1;
+	}
+
+	devname = dm_mapname(major(sbuf.st_rdev), minor(sbuf.st_rdev));
+
+	if (devname != NULL) {
+		/* We were passed a handle to a dm device.
+		 * Get the first target and operate on that instead.
+		 */
+		if (!(dev = dm_get_first_dep(devname))) {
+			free(devname);
+			return -1;
+		}
+		free(devname);
+
+		if ((unsigned int)major(dev) != 94) {
+			/* Not a DASD */
+			return -1;
+		}
+
+		/*
+		 * Hard to believe, but there's no simple way to translate
+		 * major/minor into an openable device file, so we have
+		 * to create one for ourselves.
+		 */
+		
+		sprintf(pathname, "/dev/.kpartx-node-%u-%u",
+			(unsigned int)major(dev), (unsigned int)minor(dev));
+		if ((fd_dasd = open(pathname, O_RDONLY)) == -1) {
+			/* Devicenode does not exist. Try to create one */
+			if (mknod(pathname, 0600 | S_IFBLK, dev) == -1) {
+				/* Couldn't create a device node */
+				return -1;
+			}
+			fd_dasd = open(pathname, O_RDONLY);
+			/*
+			 * The file will vanish when the last process (we)
+			 * has ceased to access it.
+			 */
+			unlink(pathname);
+		}
+		if (!fd_dasd) {
+			/* Couldn't open the device */
+			return -1;
+		}
+	} else {
+		fd_dasd = fd;
+	}
+
+	if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) {
+		goto out;
+	}
+
+	if (ioctl(fd_dasd, HDIO_GETGEO, (unsigned long)&geo) != 0) {
+		goto out;
+	}
+	
+	if (ioctl(fd_dasd, BLKGETSIZE, &disksize) != 0)
+		goto out;
+
+	if (ioctl(fd_dasd, BLKSSZGET, &blocksize) != 0)
+		goto out;
+
+	if (blocksize < 512 || blocksize > 4096)
+		goto out;
+
+	/*
+	 * Get volume label, extract name and type.
+	 */
+
+	if (!(data = (unsigned char *)malloc(blocksize)))
+		goto out;
+
+
+	if (lseek(fd_dasd, info.label_block * blocksize, SEEK_SET) == -1)
+		goto out;
+	if (read(fd_dasd, data, blocksize) == -1) {
+		perror("read");
+		goto out;
+	}
+	vtoc_ebcdic_dec(data, type, 4);
+
+	if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD")))
+		label_raw = &data[8];
+	else
+		label_raw = &data[4];
+
+	name[6] = '\0';
+	vtoc_ebcdic_dec(label_raw, name, 6);
+
+	memcpy (&vlabel, data, sizeof(volume_label_t));
+
+	/*
+	 * Three different types: CMS1, VOL1 and LNX1/unlabeled
+	 */
+	if (strncmp(type, "CMS1", 4) == 0) {
+		/*
+		 * VM style CMS1 labeled disk
+		 */
+		int *label = (int *) &vlabel;
+
+		if (label[13] != 0) {
+			/* disk is reserved minidisk */
+			blocksize = label[3];
+			offset = label[13];
+			size = (label[7] - 1)*(blocksize >> 9);
+		} else {
+			offset = (info.label_block + 1) * (blocksize >> 9);
+			size = disksize - offset;
+		}
+		sp[0].start = offset * (blocksize >> 9);
+		sp[0].size = size - offset * (blocksize >> 9);
+		retval = 1;
+	} else if ((strncmp(type, "VOL1", 4) == 0) &&
+		(!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) {
+		/*
+		 * New style VOL1 labeled disk
+		 */
+		int counter;
+
+		/* get block number and read then go through format1 labels */
+		blk = cchhb2blk(&vlabel.vtoc, &geo) + 1;
+		counter = 0;
+		if (lseek(fd_dasd, blk * blocksize, SEEK_SET) == -1)
+			goto out;
+
+		while (read(fd_dasd, data, blocksize) != -1) {
+			format1_label_t f1;
+
+			memcpy(&f1, data, sizeof(format1_label_t));
+
+			/* skip FMT4 / FMT5 / FMT7 labels */
+			if (EBCtoASC[f1.DS1FMTID] == '4'
+			    || EBCtoASC[f1.DS1FMTID] == '5'
+			    || EBCtoASC[f1.DS1FMTID] == '7') {
+			        blk++;
+				continue;
+			}
+
+			/* only FMT1 valid at this point */
+			if (EBCtoASC[f1.DS1FMTID] != '1')
+				break;
+
+			/* OK, we got valid partition data */
+		        offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
+			size  = cchh2blk(&f1.DS1EXT1.ulimit, &geo) - 
+				offset + geo.sectors;
+			sp[counter].start = offset * (blocksize >> 9);
+			sp[counter].size = size * (blocksize >> 9);
+			counter++;
+			blk++;
+		}
+		retval = counter;
+	} else {
+		/*
+		 * Old style LNX1 or unlabeled disk
+		 */
+		offset = (info.label_block + 1) * (blocksize >> 9);
+		size = disksize - offset;
+		sp[0].start = offset * (blocksize >> 9);
+		sp[0].size = size - offset * (blocksize >> 9);
+		retval = 1;
+	}
+
+ out:
+	if (data != NULL)
+		free(data);
+	if (fd_dasd != -1 && fd_dasd != fd)
+		close(fd_dasd);
+	return retval;
+}
diff --git a/kpartx/dasd.h b/kpartx/dasd.h
new file mode 100644
--- /dev/null
+++ b/kpartx/dasd.h
@@ -0,0 +1,272 @@
+/*
+ * dasd.h
+ *
+ * IBM DASD partition table handling.
+ *
+ * Mostly taken from drivers/s390/block/dasd.c
+ *
+ * Copyright (c) 2005, Hannes Reinecke, SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#ifndef _DASD_H
+#define _DASD_H
+
+typedef struct ttr 
+{
+        uint16_t tt;
+        uint8_t  r;
+} __attribute__ ((packed)) ttr_t;
+
+typedef struct cchhb 
+{
+        uint16_t cc;
+        uint16_t hh;
+        uint8_t b;
+} __attribute__ ((packed)) cchhb_t;
+
+typedef struct cchh 
+{
+        uint16_t cc;
+        uint16_t hh;
+} __attribute__ ((packed)) cchh_t;
+
+typedef struct labeldate 
+{
+        uint8_t  year;
+        uint16_t day;
+} __attribute__ ((packed)) labeldate_t;
+
+
+typedef struct volume_label 
+{
+        char volkey[4];         /* volume key = volume label                 */
+	char vollbl[4];	        /* volume label                              */
+	char volid[6];	        /* volume identifier                         */
+	uint8_t security;	        /* security byte                             */
+	cchhb_t vtoc;           /* VTOC address                              */
+	char res1[5];	        /* reserved                                  */
+        char cisize[4];	        /* CI-size for FBA,...                       */
+                                /* ...blanks for CKD                         */
+	char blkperci[4];       /* no of blocks per CI (FBA), blanks for CKD */
+	char labperci[4];       /* no of labels per CI (FBA), blanks for CKD */
+	char res2[4];	        /* reserved                                  */
+	char lvtoc[14];	        /* owner code for LVTOC                      */
+	char res3[29];	        /* reserved                                  */
+} __attribute__ ((packed)) volume_label_t;
+
+
+typedef struct extent 
+{
+        uint8_t  typeind;          /* extent type indicator                     */
+        uint8_t  seqno;            /* extent sequence number                    */
+        cchh_t llimit;          /* starting point of this extent             */
+        cchh_t ulimit;          /* ending point of this extent               */
+} __attribute__ ((packed)) extent_t;
+
+
+typedef struct dev_const 
+{
+        uint16_t DS4DSCYL;           /* number of logical cyls                  */
+        uint16_t DS4DSTRK;           /* number of tracks in a logical cylinder  */
+        uint16_t DS4DEVTK;           /* device track length                     */
+        uint8_t  DS4DEVI;            /* non-last keyed record overhead          */
+        uint8_t  DS4DEVL;            /* last keyed record overhead              */
+        uint8_t  DS4DEVK;            /* non-keyed record overhead differential  */
+        uint8_t  DS4DEVFG;           /* flag byte                               */
+        uint16_t DS4DEVTL;           /* device tolerance                        */
+        uint8_t  DS4DEVDT;           /* number of DSCB's per track              */
+        uint8_t  DS4DEVDB;           /* number of directory blocks per track    */
+} __attribute__ ((packed)) dev_const_t;
+
+
+typedef struct format1_label 
+{
+	char  DS1DSNAM[44];       /* data set name                           */
+	uint8_t  DS1FMTID;           /* format identifier                       */
+	char  DS1DSSN[6];         /* data set serial number                  */
+	uint16_t DS1VOLSQ;           /* volume sequence number                  */
+	labeldate_t DS1CREDT;     /* creation date: ydd                      */
+	labeldate_t DS1EXPDT;     /* expiration date                         */
+	uint8_t  DS1NOEPV;           /* number of extents on volume             */
+        uint8_t  DS1NOBDB;           /* no. of bytes used in last direction blk */
+	uint8_t  DS1FLAG1;           /* flag 1                                  */
+	char  DS1SYSCD[13];       /* system code                             */
+	labeldate_t DS1REFD;      /* date last referenced                    */
+        uint8_t  DS1SMSFG;           /* system managed storage indicators       */
+        uint8_t  DS1SCXTF;           /* sec. space extension flag byte          */
+        uint16_t DS1SCXTV;           /* secondary space extension value         */
+        uint8_t  DS1DSRG1;           /* data set organisation byte 1            */
+        uint8_t  DS1DSRG2;           /* data set organisation byte 2            */
+  	uint8_t  DS1RECFM;           /* record format                           */
+	uint8_t  DS1OPTCD;           /* option code                             */
+	uint16_t DS1BLKL;            /* block length                            */
+	uint16_t DS1LRECL;           /* record length                           */
+	uint8_t  DS1KEYL;            /* key length                              */
+	uint16_t DS1RKP;             /* relative key position                   */
+	uint8_t  DS1DSIND;           /* data set indicators                     */
+        uint8_t  DS1SCAL1;           /* secondary allocation flag byte          */
+  	char DS1SCAL3[3];         /* secondary allocation quantity           */
+	ttr_t DS1LSTAR;           /* last used track and block on track      */
+	uint16_t DS1TRBAL;           /* space remaining on last used track      */
+        uint16_t res1;               /* reserved                                */
+	extent_t DS1EXT1;         /* first extent description                */
+	extent_t DS1EXT2;         /* second extent description               */
+	extent_t DS1EXT3;         /* third extent description                */
+	cchhb_t DS1PTRDS;         /* possible pointer to f2 or f3 DSCB       */
+} __attribute__ ((packed)) format1_label_t;
+
+
+/*
+ * struct dasd_information_t
+ * represents any data about the data, which is visible to userspace
+ */
+typedef struct dasd_information_t {
+	unsigned int devno;		/* S/390 devno */
+	unsigned int real_devno;	/* for aliases */
+	unsigned int schid;		/* S/390 subchannel identifier */
+	unsigned int cu_type  : 16;	/* from SenseID */
+	unsigned int cu_model :  8;	/* from SenseID */
+	unsigned int dev_type : 16;	/* from SenseID */
+	unsigned int dev_model : 8;	/* from SenseID */
+	unsigned int open_count;
+	unsigned int req_queue_len;
+	unsigned int chanq_len;		/* length of chanq */
+	char type[4];			/* from discipline.name, 'none' for unknown */
+	unsigned int status;		/* current device level */
+	unsigned int label_block;	/* where to find the VOLSER */
+	unsigned int FBA_layout;	/* fixed block size (like AIXVOL) */
+	unsigned int characteristics_size;
+	unsigned int confdata_size;
+	char characteristics[64];	/* from read_device_characteristics */
+	char configuration_data[256];	/* from read_configuration_data */
+} dasd_information_t;
+
+#define DASD_IOCTL_LETTER	 'D'
+#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t)
+#define BLKGETSIZE _IO(0x12,96)
+#define BLKSSZGET _IO(0x12,104)
+
+/*
+ * Only compile this on S/390. Doesn't make any sense
+ * for other architectures.
+ */
+
+static unsigned char EBCtoASC[256] =
+{
+/* 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
+                                -ENP  ->LF             */
+	0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
+/* 0x18  CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
+                                                  -IUS */
+	0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+/* 0x20  -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
+                                -INP                   */
+	0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
+/* 0x28  -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
+                     -SW                               */
+	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    \           S     T     U     V     W     X */
+	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
+};
+
+static inline void 
+vtoc_ebcdic_dec (const unsigned char *source, char *target, int l) 
+{
+	int i;
+
+	for (i = 0; i < l; i++) 
+		target[i]=(char)EBCtoASC[(unsigned char)(source[i])];
+}
+
+/*
+ * compute the block number from a 
+ * cyl-cyl-head-head structure
+ */
+static inline int
+cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
+        return ptr->cc * geo->heads * geo->sectors +
+	       ptr->hh * geo->sectors;
+}
+
+
+/*
+ * compute the block number from a 
+ * cyl-cyl-head-head-block structure
+ */
+static inline int
+cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
+        return ptr->cc * geo->heads * geo->sectors +
+		ptr->hh * geo->sectors +
+		ptr->b;
+}
+
+#endif /* _DASD_H */
diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c
--- a/kpartx/devmapper.c
+++ b/kpartx/devmapper.c
@@ -144,3 +144,36 @@ out:
 	return mapname;
 }
 
+/*
+ * dm_get_first_dep
+ *
+ * Return the device number of the first dependend device
+ * for a given target.
+ */
+dev_t dm_get_first_dep(char *devname)
+{
+	struct dm_task *dmt;
+	struct dm_deps *dm_deps;
+	dev_t ret = 0;
+
+	if ((dmt = dm_task_create(DM_DEVICE_DEPS)) == NULL) {
+		return ret;
+	}
+	if (!dm_task_set_name(dmt, devname)) {
+		goto out;
+	}
+	if (!dm_task_run(dmt)) {
+		goto out;
+	}
+	if ((dm_deps = dm_task_get_deps(dmt)) == NULL) {
+		goto out;
+	}
+	if (dm_deps->count > 0) {
+		ret = dm_deps->device[0];
+	}
+out:
+	dm_task_destroy(dmt);
+
+	return ret;
+}
+
diff --git a/kpartx/devmapper.h b/kpartx/devmapper.h
--- a/kpartx/devmapper.h
+++ b/kpartx/devmapper.h
@@ -3,3 +3,4 @@ int dm_simplecmd (int, const char *);
 int dm_addmap (int, const char *, const char *, const char *, unsigned long);
 int dm_map_present (char *);
 const char * dm_mapname(int major, int minor);
+dev_t dm_get_first_dep(char *devname);
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
--- a/kpartx/kpartx.c
+++ b/kpartx/kpartx.c
@@ -77,6 +77,7 @@ initpts(void)
 	addpts("bsd", read_bsd_pt);
 	addpts("solaris", read_solaris_pt);
 	addpts("unixware", read_unixware_pt);
+	addpts("dasd", read_dasd_pt);
 }
 
 static char short_opts[] = "ladgvnp:t:";
diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h
--- a/kpartx/kpartx.h
+++ b/kpartx/kpartx.h
@@ -31,6 +31,7 @@ extern ptreader read_bsd_pt;
 extern ptreader read_solaris_pt;
 extern ptreader read_unixware_pt;
 extern ptreader read_gpt_pt;
+extern ptreader read_dasd_pt;
 
 char *getblock(int fd, unsigned int secnr);
 

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



  reply	other threads:[~2005-12-09 11:48 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-12-07 14:08 [kpartx] add support for S/390 DASD Hannes Reinecke
2005-12-07 22:44 ` Christophe Varoqui
2005-12-09 11:48   ` Hannes Reinecke [this message]
2005-12-07 23:03 ` Christophe Varoqui
2005-12-07 23:12   ` Christophe Varoqui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43996F07.2090206@suse.de \
    --to=hare@suse.de \
    --cc=christophe.varoqui@free.fr \
    --cc=dm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.