DISKLABEL(5)

명칭
disklabel - 디스크 팩 label

서식
<sys/disklabel.h>

해설
시스템상의 각각의 디스크나 디스크 팩은, 디스크의 지오메트리 (이)나 디스크를 분할하고 있는 파티션에 대한 상세한 정보를 제공한다 디스크 label를 가지고 있습니다. 디스크 label는 디스크가 포맷 되었을 때에 초기화되지 않으면 안되어, 나중에 disklabel(8) 프로그램에 의해 변경할 수가 있습니다. 시스템디크스드라이바나 bootstrap 프로그램이 이 정보를 사용해, 드라이브의 프로그램 방법이나, 디스크 패티션상의 파일 시스템의 찾아내는 방법을 결정합니다. 파일 시스템은, 부가적인 정보를 사용해 디스크를 가장 효과적으로 사용해, 중요한 파일 시스템 정보의 위치를 특정합니다. 각 파티션의 기술은, 파티션 타입(표준 파일, 스왑 area등 )의 식별자를 포함합니다. label의 메모리내 카피에 있는 파일 시스템 정보가 불완전한 경우에는, 파일 시스템은 그것을 갱신합니다.

label는, 드라이브의 섹터 번호 LABELSECTOR 에 있습니다. 통상은, 디스크지오메트리에 대한 정보가 없어도 찾아낼 수 있는, 섹터 0 에 있습니다. label는, 초기 bootstrap의 장소를 확보하기 위해서, 섹터의 선두로부터 오프셋(offset) LABELOFFSET 에 있습니다. label를 포함한 디스크 섹터는, 통상 읽기 전용이 되어 있습니다. 이것은, 팩으로부터 팩에의 복사나 스왑 조작시에 disklabel(8) 프로그램에 의해 필요에 따라서 행해진다 DIOCWLABEL ioctl(2) 에 의해 조심성없게 덧쓰기되지 않게 하기 (위해)때문입니다.

디스크의 메모리내 label 카피는 DIOCGDINFO ioctl(2) 그리고 얻을 수 있습니다. 이 조작은, 디스크의 임의의 파티션에 대한 블록 디바이스나 캐릭터 (``raw'') 디바이스에의 파일 기술자에 대해서 실시할 수가 있습니다. 또, 디스크의 메모리내 label 카피는 DIOCSDINFO ioctl(2) 에 의해 세트 됩니다. 파티션의 오프셋(offset)는, 일반적으로 파티션이 오픈되고 있다 때로는 변경하거나 작게 하거나는 할 수 없습니다. 다만 예외로서 디스크에 label가 발견되지 않고, 드라이버가 파티션 정보를 포함하지 않는 뼈대의 label만을 구축할 수 있을 때는, 어떤 변경도 용서됩니다. 마지막으로, DIOCWDINFO ioctl(2) 조작이 메모리내의 label를 세트 해, 디스크상의 label를 갱신합니다. 이 조작이 성공하기 위해서(때문에)는 디스크상에 label가 존재하지 않으면 안됩니다. 즉, 디스크나 디스크 팩의 초기 label는 생의 (raw) 디스크에 대해 기입하는 것으로 인스톨 되지 않으면 안됩니다. 이러한 조작은 모두, 보통 disklabel(8) 명령을 사용해 행해집니다.

<sys/disklabel.h> 그리고 지정되도록(듯이) 디스크 label의 포맷은 이하와 같이 됩니다.

    #ifndef _SYS_DISKLABEL_H_
    #define	_SYS_DISKLABEL_H_
    #ifndef _KERNEL
    #include <sys/types.h>
    #endif
    #include <sys/ioccom.h>
    /*
     * 디스크 기술 테이블, disktab(5)를 참조
     */
    #define	_PATH_DISKTAB	"/etc/disktab"
    #define	DISKTAB		"/etc/disktab"		/* 비추천 */
    /*
     * 각 디스크는 하드웨아디스크지오메트리, 파일 시스템 파티션,
     * 드라이브 고유의 정보에 대한 정보를 포함한 label를 가지고 있습니다.
     * label는 블록 0 이나 1, 즉 bootstrap등을 위한 장소를 비워
     * 가능한 한 선두의 오프셋(offset)에 있습니다.
     */
    /*
     * XXX 이러한 정보는 콘트롤러마다 (또는 드라이브마다)에 어딘가 다른 곳에서
     * XXX 정의 되는 것이 당연해, 여기서 정의해야 하지는 않습니다!
     */
    #ifdef __i386__
    #define LABELSECTOR	1			/* sector containing label */
    #define LABELOFFSET	0			/* offset of label in sector */
    #endif
    #ifdef __alpha__
    #define LABELSECTOR	0
    #define LABELOFFSET	64
    #endif
    #ifndef	LABELSECTOR
    #define LABELSECTOR	0			/* label를 포함한 섹터 */
    #endif
    #ifndef	LABELOFFSET
    #define LABELOFFSET	64			/* 섹터내의 label의 오프셋(offset) */
    #endif
    #define DISKMAGIC	((u_long32_t) 0x82564557) /* 디스크의 magic number */
    #ifndef MAXPARTITIONS
    #define	MAXPARTITIONS	8
    #endif
    #define	LABEL_PART	2		/* 파티션은 label를 포함한다 */
    #define	RAW_PART	2		/* 파티션은 디스크 전체를 포함한다 */
    #define	SWAP_PART	1		/* 파티션은 통상은 스왑을 포함한다 */
    #ifndef LOCORE
    struct disklabel {
    	u_int32_t d_magic;		/* magic number */
    	u_int16_t d_type;		/* 드라이브 타입 */
    	u_int16_t d_subtype;		/* 콘트롤러 /d_type 에 고유 */
    	char	  d_typename[16];	/* 타입명, 예를 들어 "eagle" */
    	/*
    	 * d_packname 는, 팩 식별자를 포함해, 디스크상이나 메모리내 카피의
    	 * 디스크 label를 읽었을 때에 돌려주어집니다.
    	 * d_boot0 와 d_boot1 는, /boot 에 있는 일차 (block 0) 또는
    	 * 2차 (block 1-15) bootstrap의 (생략 가능한) 이름입니다.
    	 * 이 이름은, /etc/disktab 로부터 값을 꺼내기 위해서(때문에) getdiskbyname(3)
    	 * (을)를 사용하는 경우에 돌려주어집니다.
    	 */
    	union {
    		char	un_d_packname[16];	/* 팩 식별자 */
    		struct {
    			char *un_d_boot0;	/* 일차 bootstrap명 */
    			char *un_d_boot1;	/* 2차 bootstrap명 */
    		} un_b;
    	} d_un;
    #define d_packname	d_un.un_d_packname
    #define d_boot0		d_un.un_b.un_d_boot0
    #define d_boot1		d_un.un_b.un_d_boot1
    			/* 디스크지오메트리 */
    	u_int32_t d_secsize;	/* 섹터 근처의 바이트수 */
    	u_int32_t d_nsectors;	/* 트럭 근처의 데이터 섹터수 */
    	u_int32_t d_ntracks;	/* 실린더 근처의 트럭수 */
    	u_int32_t d_ncylinders;	/* 유니트 근처의 데이터 실린더수 */
    	u_int32_t d_secpercyl;	/* 실린더 근처의 데이터 섹터수 */
    	u_int32_t d_secperunit;	/* 유니트 근처의 데이터 섹터수 */
    	/*
    	 * 이하의 예비 (배드 섹터 치환)는 in d_nsectors 나 d_secpercyl
    	 * 에는 셀 수 없습니다.
    	 * 예비 섹터는, 각 트럭 또는 실린더의 말미의 장소를 차지한다
    	 * 물리 섹터에 있기로 하겠습니다.
    	 */
    	u_int16_t d_sparespertrack;	/* 트럭 근처의 예비 섹터 */
    	u_int16_t d_sparespercyl;	/* 실린더 근처의 예비 섹터 */
    	/*
    	 * 메인트넌스, 치환, 배치 기술 area등을
    	 * 포함한 교체 실린더
    	 */
    	u_int32_t d_acylinders;		/* 유니트 근처의 교체 실린더 */
    			/* 하드웨어 특성 */
    	/*
    	* d_interleave, d_trackskew, d_cylskew 는, 늦은 콘트롤러의
    	* 벌충에 사용하기 위한, 미디어 포맷중의
    	* 치우침을 기술합니다.
    	* interleave 는, 포맷시에 포매터나 콘트롤러에
    	* 따라서 설정되는 물리 세크타인타리브입니다.
    	* 인타리브가 사용되고 있을 때, 논리적으로 서로 이웃이 된 섹터는
    	* 물리적으로는 연속이 아니고, 몇개의 섹터에 분단 되고 있습니다.
    	* 이것은 논리 섹터 근처의 물리 섹터 통과율로서 지정됩니다.
    	* 즉,1:1 의 인타리브는 연속한 레이아웃을 의미해,
    	* 2:1 (은)는 논리 섹터 0 이 논리 섹터 1 에서 1 섹터 떨어져 있는 것
    	* (을)를 의미합니다.
    	* d_trackskew 는, 동일 실린더상에서 트럭 N-1 상의 섹터 0 으로부터
    	* 트럭 N 의 섹터 0 의 상대적인 오프셋(offset)입니다.
    	* 마지막 d_cylskew 는, 실린더 N-1 상의 섹터 0 으로부터 실린더 N
    	* 위의 섹터 0 의 상대적인 오프셋(offset)입니다.
    	*/
    	u_int16_t d_rpm;		/* 회전 스피드 */
    	u_int16_t d_interleave;		/* 하드웨아세크타인타리브 */
    	u_int16_t d_trackskew;		/* 트럭 근처의 섹터 0 skew */
    	u_int16_t d_cylskew;		/* 실린더 근처의 섹터 0 skew */
    	u_int32_t d_headswitch;		/* 하드 스윗치 시간 usec */
    	u_int32_t d_trkseek;		/* 트럭간 시크 usec */
    	u_int32_t d_flags;		/* 일반 플래그 */
    #define NDDATA 5
    	u_int32_t d_drivedata[NDDATA];	/* 드라이브의 형태 고유의 정보 */
    #define NSPARE 5
    	u_int32_t d_spare[NSPARE];	/* 장래 사용하기 위한 예비 */
    	u_int32_t d_magic2;		/* magic number (재차) */
    	u_int16_t d_checksum;		/* 데이터를 포함한 파티션의 xor */
    			/* 파일 시스템과 파티션 정보 */
    	u_int16_t d_npartitions;	/* 후에 계속되는 파티션수 */
    	u_int32_t d_bbsize;		/* sn0 의 부트 area의 크기(바이트 단위) */
    	u_int32_t d_sbsize;		/* fs 슈퍼 블록의 최대 사이즈(바이트 단위) */
    	struct	partition {		/* 파티션 테이블 */
    		u_int32_t p_size;	/* 파티션내의 섹터수 */
    		u_int32_t p_offset;	/* 개시 섹터 */
    		u_int32_t p_fsize;	/* 파일 시스템 규정 fragment 사이즈 */
    		u_int8_t p_fstype;	/* 파일 시스템 타입, 아래와 같이 참조 */
    		u_int8_t p_frag;	/* 블록 근처의 파일 시스템 fragment */
    		union {
    			u_int16_t cpg;	/* UFS: FS 그룹 근처의 실린더수 */
    			u_int16_t sgs;	/* LFS: FS 세그먼트(segment) 쉬프트 */
    		} __partition_u1;
    #define	p_cpg	__partition_u1.cpg
    #define	p_sgs	__partition_u1.sgs
    	} d_partitions[MAXPARTITIONS];	/* 실제로는 좀 더 있다 */
    };
    #else /* LOCORE */
    	/*
    	 * asm 부트 파일용의 오프셋(offset)
    	 */
    	.set	d_secsize, 40
    	.set	d_nsectors, 44
    	.set	d_ntracks, 48
    	.set	d_ncylinders, 52
    	.set	d_secpercyl, 56
    	.set	d_secperunit, 60
    	.set	d_end_, 276		/* 디스크 label의 크기 */
    #endif /* LOCORE */
    /* d_type values: */
    #define	DTYPE_SMD		1		/* SMD, XSMD; VAX hp/up */
    #define	DTYPE_MSCP		2		/* MSCP */
    #define	DTYPE_DEC		3		/* 그 외의 DEC (rk, rl) */
    #define	DTYPE_SCSI		4		/* SCSI */
    #define	DTYPE_ESDI		5		/* ESDI 인터페이스 */
    #define	DTYPE_ST506		6		/* ST506 외 */
    #define	DTYPE_HPIB		7		/* HP-IB 상의 CS/80 */
    #define	DTYPE_HPFL		8		/* HP 파이버 링크 */
    #define	DTYPE_FLOPPY		10		/* 플로피 */
    #define	DTYPE_CCD		11		/* 콘카치네이트화 디스크 */
    #define	DTYPE_VINUM		12		/* vinum 볼륨 */
    #define	DTYPE_DOC2K		13		/* Msys DiskOnChip */
    #if defined(PC98) && ! defined(PC98_ATCOMPAT)
    #define	DSTYPE_SEC256		0x80		/* 물리 섹터 사이즈는 256 */
    #endif
    #ifdef DKTYPENAMES
    static char *dktypenames[] = {
    	"unknown",
    	"SMD",
    	"MSCP",
    	"old DEC",
    	"SCSI",
    	"ESDI",
    	"ST506",
    	"HP-IB",
    	"HP-FL",
    	"type 9",
    	"floppy",
    	"CCD",
    	"Vinum",
    	"DOC2K",
    	NULL
    };
    #define DKMAXTYPES	(sizeof(dktypenames) / sizeof(dktypenames[0]) - 1)
    #endif
    /*
     * 파일 시스템 타입과 버젼
     * 파티션 근처의 다른 파일 시스템 고유 정보에 사용됩니다.
     */
    #define	FS_UNUSED	0		/* 미사용 */
    #define	FS_SWAP		1		/* 스왑 */
    #define	FS_V6		2		/* 제 6 판 */
    #define	FS_V7		3		/* 제 7 판 */
    #define	FS_SYSV		4		/* System V */
    #define	FS_V71K		5		/* 7 판 1K 블록 (4.1, 2.9) */
    #define	FS_V8		6		/* 8 판 4K 블록 */
    #define	FS_BSDFFS	7		/* 4.2BSD 고속 파일 시스템 */
    #define	FS_MSDOS	8		/* MSDOS 파일 시스템 */
    #define	FS_BSDLFS	9		/* 4.4BSD 로그 구조 파일 시스템 */
    #define	FS_OTHER	10		/* 사용중이지만 미지/미서포트 */
    #define	FS_HPFS		11		/* OS/2 고성능 파일 시스템 */
    #define	FS_ISO9660	12		/* ISO 9660, 통상은 CD-ROM */
    #define	FS_BOOT		13		/* bootstrap를 포함한 파티션 */
    #define	FS_VINUM	14		/* Vinum 드라이브 */
    #ifdef	DKTYPENAMES
    static char *fstypenames[] = {
    	"unused",
    	"swap",
    	"Version 6",
    	"Version 7",
    	"System V",
    	"4.1BSD",
    	"Eighth Edition",
    	"4.2BSD",
    	"MSDOS",
    	"4.4LFS",
    	"unknown",
    	"HPFS",
    	"ISO9660",
    	"boot",
    	"vinum",
    	NULL
    };
    #define FSMAXTYPES	(sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
    #endif
    /*
     * 다양한 드라이브가 공유하는 플래그
     */
    #define		D_REMOVABLE	0x01		/* 리모트 미디어 */
    #define		D_ECC		0x02		/* ECC 서포트 */
    #define		D_BADSECT	0x04		/* 잘못된 섹터 포워드의 서포트 */
    #define		D_RAMDISK	0x08		/* 디스크 에뮬레이터 */
    #define		D_CHAIN		0x10		/* 연속 전송 가능 */
    /*
     * SMD 의 드라이브 데이터
     */
    #define	d_smdflags	d_drivedata[0]
    #define		D_SSE		0x1		/* 섹터 스킵의 서포트 */
    #define	d_mindist	d_drivedata[1]
    #define	d_maxdist	d_drivedata[2]
    #define	d_sdist		d_drivedata[3]
    /*
     * ST506 의 드라이브 데이터
     */
    #define d_precompcyl	d_drivedata[0]
    #define d_gap3		d_drivedata[1]		/* 포맷시에게만 사용 */
    /*
     * SCSI 의 드라이브 데이터
     */
    #define	d_blind		d_drivedata[0]
    #ifndef LOCORE
    /*
    * 포맷이나 생의 조작을 할 때에 사용된다
    * 구조체로, 데이터나 레지스터치를 돌려줍니다.
    * 레지스터의 식별과 포맷은,
    * 디바이스 의존, 드라이버 의존입니다.
    */
    struct format_op {
    	char	*df_buf;
    	int	 df_count;		/* 치-결과 */
    	daddr_t	 df_startblk;
    	int	 df_reg[8];		/* 결과 */
    };
    /*
     * 디스크상의 파티션에 관한 정보를
     * 꺼내기 위해서(때문에) 내부에서 사용되는 구조체
     */
    struct partinfo {
    	struct disklabel *disklab;
    	struct partition *part;
    };
    /* DOS 파티션 테이블 -- 부트 블록에 있습니다 */
    #if defined(PC98) && ! defined(PC98_ATCOMPAT)
    #define	DOSBBSECTOR	0	/* DOS 부트 블록의 상대 섹터 번호 */
    #define DOSLABELSECTOR	1	/* 0: 256b/s, 1: 512b/s */
    #define	DOSPARTOFF	0
    #define NDOSPART	16
    #define	DOSPTYP_386BSD	0x94	/* 386BSD 파티션 타입 */
    #define	MBR_PTYPE_FreeBSD 0x94	/* FreeBSD 파티션 타입 */
    struct dos_partition {
        	unsigned char	dp_mid;
    #define DOSMID_386BSD		(0x14|0x80) /* 386bsd|bootable */
    	unsigned char	dp_sid;
    #define DOSSID_386BSD		(0x44|0x80) /* 386bsd|active */
    	unsigned char	dp_dum1;
    	unsigned char	dp_dum2;
    	unsigned char	dp_ipl_sct;
    	unsigned char	dp_ipl_head;
    	unsigned short	dp_ipl_cyl;
    	unsigned char	dp_ssect;	/* 선두 섹터 */
    	unsigned char	dp_shd;		/* 선두 헤드 */
    	unsigned short	dp_scyl;	/* 선두 실린더 */
    	unsigned char	dp_esect;	/* 종단 섹터 */
    	unsigned char	dp_ehd;		/* 종단 헤드 */
    	unsigned short	dp_ecyl;	/* 종단 실린더 */
    	unsigned char	dp_name[16];
    };
    #else /* IBMPC */
    #define DOSBBSECTOR	0	/* DOS 부트 블록의 상대 섹터 번호 */
    #define DOSPARTOFF	446
    #define NDOSPART	4
    #define	DOSPTYP_386BSD	0xa5	/* 386BSD 파티션 타입 */
    struct dos_partition {
    	unsigned char	dp_flag;	/* bootstrap 플래그 */
    	unsigned char	dp_shd;		/* 선두 헤드 */
    	unsigned char	dp_ssect;	/* 선두 섹터 */
    	unsigned char	dp_scyl;	/* 선두 실린더 */
    	unsigned char	dp_typ;		/* 파티션 타입 */
    	unsigned char	dp_ehd;		/* 종단 헤드 */
    	unsigned char	dp_esect;	/* 종단 섹터 */
    	unsigned char	dp_ecyl;	/* 종단 실린더 */
    	u_int32_t	dp_start;	/* 절대적인 선두 섹터 번호 */
    	u_int32_t	dp_size;	/* 섹터수에서의 파티션 사이즈 */
    };
    #endif
    #define DPSECT(s) ((s) & 0x3f)		/* 섹터용의 비트의 분리 */
    #define DPCYL(c, s) ((c) + (((s) & 0xc0)<<2)) /* 이쪽은 실린더용 */
    /*
     * 디스크 고유의 ioctl
     */
    		/* 디스크 label의 취득과 설정; 내부에서는 DIOCGPART 가 사용된다 */
    #define DIOCGDINFO	_IOR('d', 101, struct disklabel)/* 취득 */
    #define DIOCSDINFO	_IOW('d', 102, struct disklabel)/* 설정 */
    #define DIOCWDINFO	_IOW('d', 103, struct disklabel)/* 설정, 디스크 갱신 */
    #define DIOCGPART	_IOW('d', 104, struct partinfo) /* 파티션 취득 */
    #define DIOCWLABEL	_IOW('d', 109, int)	/* label의 기입가능/불가 */
    #ifdef _KERNEL
    /*
     * XXX 디스크마이나 번호의 인코딩은 다른 곳에 있어야 합니다.
     *
     * 보다 좋을 가능성의 인코딩에 대해서는 <sys/reboot.h> 을 참조해 주십시오.
     *
     * "cpio -H newc" 로 큰 마이나 번호의 디바이스 파일 (그러나 2^31 미만)
     * (을)를 백업 가능합니다. 낡은 cpio 포맷과 전 tar 포맷에서는
     * 비트수가 불충분하고, 또 cpio tar 는 비트 상실을 보고하지 않습니다.
     * 또, 부호 확장에 버그가 있습니다.
     */
    /*
           3                   2                   1                   0
         1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        _________________________________________________________________
        | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
        -----------------------------------------------------------------
        |    TYPE     |UNIT_2 | SLICE   |  MAJOR?        |  UNIT   |PART |
        -----------------------------------------------------------------
     */
    #define	dkmakeminor(unit, slice, part) \
    	(((slice) << 16) | (((unit) & 0x1e0) << 16) | \
    	(((unit) & 0x1f) << 3) | (part))
    static __inline dev_t
    dkmodpart(dev_t dev, int part)
    {
    	return (makedev(major(dev), (minor(dev) & ~7) | part));
    }
    static __inline dev_t
    dkmodslice(dev_t dev, int slice)
    {
    	return (makedev(major(dev), (minor(dev) & ~0x1f0000) | (slice << 16)));
    }
    #define	dkpart(dev)		(minor(dev) & 7)
    #define	dkslice(dev)		((minor(dev) >> 16) & 0x1f)
    #define	dktype(dev)       	((minor(dev) >> 25) & 0x7f)
    static __inline u_int
    dkunit(dev_t dev)
    {
    	return (((minor(dev) >> 16) & 0x1e0) | ((minor(dev) >> 3) & 0x1f));
    }
    struct	buf;
    struct	buf_queue_head;
    int	bounds_check_with_label __P((struct buf *bp, struct disklabel *lp,
    				     int wlabel));
    void	diskerr __P((struct buf *bp, char *what, int pri, int blkdone,
    		     struct disklabel *lp));
    void	disksort __P((struct buf *ap, struct buf *bp));
    u_int	dkcksum __P((struct disklabel *lp));
    char	*readdisklabel __P((dev_t dev, struct disklabel *lp));
    void	bufqdisksort __P((struct buf_queue_head *ap, struct buf *bp));
    int	setdisklabel __P((struct disklabel *olp, struct disklabel *nlp,
    			  u_long openmask));
    int	writedisklabel __P((dev_t dev, struct disklabel *lp));
    #ifdef __alpha__
    void	alpha_fix_srm_checksum __P((struct buf *bp));
    #endif
    #endif /* _KERNEL */
    #endif /* LOCORE */
    #ifndef _KERNEL
    __BEGIN_DECLS
    struct disklabel *getdiskbyname __P((const char *));
    __END_DECLS
    #endif
    #endif /* ! _SYS_DISKLABEL_H_ */

관련 항목
disktab(5), disklabel(8)