fdisksunlabel.c
来自「Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分」· C语言 代码 · 共 747 行 · 第 1/2 页
C
747 行
/* * fdisksunlabel.c * * I think this is mostly, or entirely, due to * Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996 * * Merged with fdisk for other architectures, aeb, June 1998. * * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br> * Internationalization */#include <stdio.h> /* stderr */#include <stdlib.h> /* qsort */#include <string.h> /* strstr */#include <unistd.h> /* write */#include <sys/ioctl.h> /* ioctl */#include <sys/stat.h> /* stat */#include <sys/sysmacros.h> /* major */#include "nls.h"#include <endian.h>#include "../defines.h" /* for HAVE_scsi_h */#ifdef HAVE_scsi_h#define u_char unsigned char#include <scsi/scsi.h> /* SCSI_IOCTL_GET_IDLUN */#undef u_char#endif#include <linux/major.h> /* FLOPPY_MAJOR */#include "common.h"#include "fdisk.h"#include "fdisksunlabel.h"static int other_endian = 0;static int scsi_disk = 0;static int floppy = 0;#define LINUX_SWAP 0x82#define LINUX_NATIVE 0x83struct systypes sun_sys_types[] = { {0, N_("Empty")}, {1, N_("Boot")}, {2, N_("SunOS root")}, {SUNOS_SWAP, N_("SunOS swap")}, {4, N_("SunOS usr")}, {WHOLE_DISK, N_("Whole disk")}, {6, N_("SunOS stand")}, {7, N_("SunOS var")}, {8, N_("SunOS home")}, {LINUX_SWAP, N_("Linux swap")}, {LINUX_NATIVE, N_("Linux native")}, {0x8e, N_("Linux LVM")}, {0xfd, N_("Linux raid autodetect")},/* New (2.2.x) raid partition with autodetect using persistent superblock */ { 0, NULL }};static inline unsigned short __swap16(unsigned short x) { return (((__u16)(x) & 0xFF) << 8) | (((__u16)(x) & 0xFF00) >> 8);}static inline __u32 __swap32(__u32 x) { return (((__u32)(x) & 0xFF) << 24) | (((__u32)(x) & 0xFF00) << 8) | (((__u32)(x) & 0xFF0000) >> 8) | (((__u32)(x) & 0xFF000000) >> 24);}intget_num_sectors(struct sun_partition p) { return SSWAP32(p.num_sectors);}#ifndef IDE0_MAJOR#define IDE0_MAJOR 3#endif#ifndef IDE1_MAJOR#define IDE1_MAJOR 22#endifvoid guess_device_type(int fd) { struct stat bootstat; if (fstat (fd, &bootstat) < 0) { scsi_disk = 0; floppy = 0; } else if (S_ISBLK(bootstat.st_mode) && (major(bootstat.st_rdev) == IDE0_MAJOR || major(bootstat.st_rdev) == IDE1_MAJOR)) { scsi_disk = 0; floppy = 0; } else if (S_ISBLK(bootstat.st_mode) && major(bootstat.st_rdev) == FLOPPY_MAJOR) { scsi_disk = 0; floppy = 1; } else { scsi_disk = 1; floppy = 0; }}static voidset_sun_partition(int i, unsigned int start, unsigned int stop, int sysid) { sunlabel->infos[i].id = sysid; sunlabel->partitions[i].start_cylinder = SSWAP32(start / (heads * sectors)); sunlabel->partitions[i].num_sectors = SSWAP32(stop - start); set_changed(i);}voidsun_nolabel(void) { sun_label = 0; sunlabel->magic = 0; partitions = 4;}intcheck_sun_label(void) { unsigned short *ush; int csum; if (sunlabel->magic != SUN_LABEL_MAGIC && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) { sun_label = 0; other_endian = 0; return 0; } other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED); ush = ((unsigned short *) (sunlabel + 1)) - 1; for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--; if (csum) { fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n" "Probably you'll have to set all the values,\n" "e.g. heads, sectors, cylinders and partitions\n" "or force a fresh label (s command in main menu)\n")); } else { heads = SSWAP16(sunlabel->ntrks); cylinders = SSWAP16(sunlabel->ncyl); sectors = SSWAP16(sunlabel->nsect); } update_units(); sun_label = 1; partitions = 8; return 1;}struct sun_predefined_drives { char *vendor; char *model; unsigned short sparecyl; unsigned short ncyl; unsigned short nacyl; unsigned short pcylcount; unsigned short ntrks; unsigned short nsect; unsigned short rspeed;} sun_drives[] = {{"Quantum","ProDrive 80S",1,832,2,834,6,34,3662},{"Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},{"CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},{"IBM","DPES-31080",0,4901,2,4903,4,108,5400},{"IBM","DORS-32160",0,1015,2,1017,67,62,5400},{"IBM","DNES-318350",0,11199,2,11474,10,320,7200},{"SEAGATE","ST34371",0,3880,2,3882,16,135,7228},{"","SUN0104",1,974,2,1019,6,35,3662},{"","SUN0207",4,1254,2,1272,9,36,3600},{"","SUN0327",3,1545,2,1549,9,46,3600},{"","SUN0340",0,1538,2,1544,6,72,4200},{"","SUN0424",2,1151,2,2500,9,80,4400},{"","SUN0535",0,1866,2,2500,7,80,5400},{"","SUN0669",5,1614,2,1632,15,54,3600},{"","SUN1.0G",5,1703,2,1931,15,80,3597},{"","SUN1.05",0,2036,2,2038,14,72,5400},{"","SUN1.3G",6,1965,2,3500,17,80,5400},{"","SUN2.1G",0,2733,2,3500,19,80,5400},{"IOMEGA","Jaz",0,1019,2,1021,64,32,5394},};static struct sun_predefined_drives *sun_autoconfigure_scsi(void) { struct sun_predefined_drives *p = NULL;#ifdef SCSI_IOCTL_GET_IDLUN unsigned int id[2]; char buffer[2048]; char buffer2[2048]; FILE *pfd; char *vendor; char *model; char *q; int i; if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) { sprintf(buffer, "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",#if 0 ((id[0]>>24)&0xff)-/*PROC_SCSI_SCSI+PROC_SCSI_FILE*/33,#else /* This is very wrong (works only if you have one HBA), but I haven't found a way how to get hostno from the current kernel */ 0,#endif (id[0]>>16)&0xff, id[0]&0xff, (id[0]>>8)&0xff); pfd = fopen("/proc/scsi/scsi","r"); if (pfd) { while (fgets(buffer2,2048,pfd)) { if (!strcmp(buffer, buffer2)) { if (fgets(buffer2,2048,pfd)) { q = strstr(buffer2,"Vendor: "); if (q) { q += 8; vendor = q; q = strstr(q," "); *q++ = 0; /* truncate vendor name */ q = strstr(q,"Model: "); if (q) { *q = 0; q += 7; model = q; q = strstr(q," Rev: "); if (q) { *q = 0; for (i = 0; i < SIZE(sun_drives); i++) { if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor)) continue; if (!strstr(model, sun_drives[i].model)) continue; printf(_("Autoconfigure found a %s%s%s\n"),sun_drives[i].vendor,(*sun_drives[i].vendor) ? " " : "",sun_drives[i].model); p = sun_drives + i; break; } } } } } break; } } fclose(pfd); } }#endif return p;}void create_sunlabel(void){ struct hd_geometry geometry; unsigned int ndiv; int i; unsigned char c; struct sun_predefined_drives *p = NULL; fprintf(stderr, _("Building a new sun disklabel. Changes will remain in memory only,\n" "until you decide to write them. After that, of course, the previous\n" "content won't be recoverable.\n\n"));#if BYTE_ORDER == LITTLE_ENDIAN other_endian = 1;#else other_endian = 0;#endif memset(MBRbuffer, 0, sizeof(MBRbuffer)); sunlabel->magic = SSWAP16(SUN_LABEL_MAGIC); if (!floppy) { puts(_("Drive type\n" " ? auto configure\n" " 0 custom (with hardware detected defaults)")); for (i = 0; i < SIZE(sun_drives); i++) { printf(" %c %s%s%s\n", i + 'a', sun_drives[i].vendor, (*sun_drives[i].vendor) ? " " : "", sun_drives[i].model); } for (;;) { c = read_char(_("Select type (? for auto, 0 for custom): ")); if (c >= 'a' && c < 'a' + SIZE(sun_drives)) { p = sun_drives + c - 'a'; break; } else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) { p = sun_drives + c - 'A'; break; } else if (c == '0') { break; } else if (c == '?' && scsi_disk) { p = sun_autoconfigure_scsi(); if (!p) printf(_("Autoconfigure failed.\n")); else break; } } } if (!p || floppy) { if (!ioctl(fd, HDIO_GETGEO, &geometry)) { heads = geometry.heads; sectors = geometry.sectors; cylinders = geometry.cylinders; } else { heads = 0; sectors = 0; cylinders = 0; } if (floppy) { sunlabel->nacyl = 0; sunlabel->pcylcount = SSWAP16(cylinders); sunlabel->rspeed = SSWAP16(300); sunlabel->ilfact = SSWAP16(1); sunlabel->sparecyl = 0; } else { heads = read_int(1,heads,1024,0,_("Heads")); sectors = read_int(1,sectors,1024,0,_("Sectors/track")); if (cylinders) cylinders = read_int(1,cylinders-2,65535,0,_("Cylinders")); else cylinders = read_int(1,0,65535,0,_("Cylinders")); sunlabel->nacyl = SSWAP16(read_int(0,2,65535,0, _("Alternate cylinders"))); sunlabel->pcylcount = SSWAP16(read_int(0,cylinders+SSWAP16(sunlabel->nacyl), 65535,0,_("Physical cylinders"))); sunlabel->rspeed = SSWAP16(read_int(1,5400,100000,0, _("Rotation speed (rpm)"))); sunlabel->ilfact = SSWAP16(read_int(1,1,32,0,_("Interleave factor"))); sunlabel->sparecyl = SSWAP16(read_int(0,0,sectors,0, _("Extra sectors per cylinder"))); } } else { sunlabel->sparecyl = SSWAP16(p->sparecyl); sunlabel->ncyl = SSWAP16(p->ncyl); sunlabel->nacyl = SSWAP16(p->nacyl); sunlabel->pcylcount = SSWAP16(p->pcylcount); sunlabel->ntrks = SSWAP16(p->ntrks); sunlabel->nsect = SSWAP16(p->nsect); sunlabel->rspeed = SSWAP16(p->rspeed); sunlabel->ilfact = SSWAP16(1); cylinders = p->ncyl; heads = p->ntrks; sectors = p->nsect; puts(_("You may change all the disk params from the x menu")); } snprintf(sunlabel->info, sizeof(sunlabel->info), "%s%s%s cyl %d alt %d hd %d sec %d", p ? p->vendor : "", (p && *p->vendor) ? " " : "", p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")), cylinders, SSWAP16(sunlabel->nacyl), heads, sectors); sunlabel->ntrks = SSWAP16(heads); sunlabel->nsect = SSWAP16(sectors); sunlabel->ncyl = SSWAP16(cylinders); if (floppy) set_sun_partition(0, 0, cylinders * heads * sectors, LINUX_NATIVE); else { if (cylinders * heads * sectors >= 150 * 2048) { ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */ } else ndiv = cylinders * 2 / 3; set_sun_partition(0, 0, ndiv * heads * sectors, LINUX_NATIVE); set_sun_partition(1, ndiv * heads * sectors, cylinders * heads * sectors, LINUX_SWAP); sunlabel->infos[1].flags |= 0x01; /* Not mountable */ } set_sun_partition(2, 0, cylinders * heads * sectors, WHOLE_DISK); { unsigned short *ush = (unsigned short *)sunlabel;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?