/* * edisk - edit gpt disk partition table */#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>#include <disk.h>#include "edit.h"#include <mp.h>#include <libsec.h> #define TB (1024LL*GB)#define GB (1024*1024*1024)#define MB (1024*1024)#define KB (1024) typedef struct Header Header;typedef struct Entry Entry; typedef struct Type Type;typedef struct Flag Flag;typedef struct Gptpart Gptpart; struct Header{ uchar sig[8]; uchar rev[4]; uchar hdrsiz[4]; uchar hdrcrc[4]; uchar zero[4]; uchar selflba[8]; uchar backlba[8]; uchar firstlba[8]; uchar lastlba[8]; uchar devid[16]; uchar tablba[8]; uchar entrycount[4]; uchar entrysize[4]; uchar tabcrc[4];}; struct Entry{ uchar typeid[16]; uchar partid[16]; uchar firstlba[8]; uchar lastlba[8]; uchar attr[8]; uchar name[72];}; enum { Headersiz = 92, Entrysiz = 16+16+8+8+8+72,}; struct Type { uchar uuid[16]; char *name; char *desc;}; struct Flag { uvlong f; char c; char *desc;}; struct Gptpart { Part; Type *type; /* nil when not in use */ uvlong attr; uchar uuid[16]; Rune label[72+1]; char namebuf[8];}; static uchar *pmbr;static Header *phdr;static Header *bhdr; static vlong partoff;static vlong partend; static Gptpart *parts;static int nparts; static uchar devid[16];static uchar zeros[16]; /* RFC4122, but in little endian format */#define UU(a,b,c,d,e) { \ (a)&255,((a)>>8)&255,((a)>>16)&255,((a)>>24)&255, \ (b)&255,((b)>>8)&255, \ (c)&255,((c)>>8)&255, \ ((d)>>8)&255,(d)&255, \ ((e)>>40)&255, ((e)>>32)&255, ((e)>>24)&255, ((e)>>16)&255, ((e)>>8)&255, (e)&255} static Type types[256] = {{UU(0x00000000,0x0000,0x0000,0x0000,0x000000000000ULL), "", "Unused entry"},{UU(0x024DEE41,0x33E7,0x11D3,0x9D69,0x0008C781F39FULL), "mbr", "MBR partition"},{UU(0xC12A7328,0xF81F,0x11D2,0xBA4B,0x00A0C93EC93BULL), "esp", "EFI System Partition"},{UU(0x21686148,0x6449,0x6E6F,0x744E,0x656564454649ULL), "bios", "BIOS boot partition"},{UU(0xD3BFE2DE,0x3DAF,0x11DF,0xBA40,0xE3A556D89593ULL), "iffs", "Intel Fast Flash"},{UU(0xF4019732,0x066E,0x4E12,0x8273,0x346C5641494FULL), "sony", "Sony boot"},{UU(0xBFBFAFE7,0xA34F,0x448A,0x9A5B,0x6213EB736C22ULL), "lenovo", "Lenovo boot"},{UU(0xE3C9E316,0x0B5C,0x4DB8,0x817D,0xF92DF00215AEULL), "msr", "Microsoft Reserved Partition"},{UU(0xEBD0A0A2,0xB9E5,0x4433,0x87C0,0x68B6B72699C7ULL), "dos", "Microsoft Basic data"},{UU(0x5808C8AA,0x7E8F,0x42E0,0x85D2,0xE1E90434CFB3ULL), "ldmm", "Logical Disk Manager metadata"},{UU(0xAF9B60A0,0x1431,0x4F62,0xBC68,0x3311714A69ADULL), "ldmd", "Logical Disk Manager data"},{UU(0xDE94BBA4,0x06D1,0x4D40,0xA16A,0xBFD50179D6ACULL), "recovery", "Windows Recovery Environment"},{UU(0x37AFFC90,0xEF7D,0x4E96,0x91C3,0x2D7AE055B174ULL), "gpfs", "IBM General Parallel File System"},{UU(0xE75CAF8F,0xF680,0x4CEE,0xAFA3,0xB001E56EFC2DULL), "storagespaces", "Storage Spaces"},{UU(0x75894C1E,0x3AEB,0x11D3,0xB7C1,0x7B03A0000000ULL), "hpuxdata", "HP-UX Data"},{UU(0xE2A1E728,0x32E3,0x11D6,0xA682,0x7B03A0000000ULL), "hpuxserv", "HP-UX Service"},{UU(0x0FC63DAF,0x8483,0x4772,0x8E79,0x3D69D8477DE4ULL), "linuxdata", "Linux Data"},{UU(0xA19D880F,0x05FC,0x4D3B,0xA006,0x743F0F84911EULL), "linuxraid", "Linux RAID"},{UU(0x0657FD6D,0xA4AB,0x43C4,0x84E5,0x0933C84B4F4FULL), "linuxswap", "Linux Swap"},{UU(0xE6D6D379,0xF507,0x44C2,0xA23C,0x238F2A3DF928ULL), "linuxlvm", "Linux Logical Volume Manager"},{UU(0x933AC7E1,0x2EB4,0x4F13,0xB844,0x0E14E2AEF915ULL), "linuxhome", "Linux /home"},{UU(0x3B8F8425,0x20E0,0x4F3B,0x907F,0x1A25A76F98E8ULL), "linuxsrv", "Linux /srv"},{UU(0x7FFEC5C9,0x2D00,0x49B7,0x8941,0x3EA10A5586B7ULL), "linuxcrypt", "Linux Plain dm-crypt"},{UU(0xCA7D7CCB,0x63ED,0x4C53,0x861C,0x1742536059CCULL), "luks", "LUKS"},{UU(0x8DA63339,0x0007,0x60C0,0xC436,0x083AC8230908ULL), "linuxreserved", "Linux Reserved"},{UU(0x83BD6B9D,0x7F41,0x11DC,0xBE0B,0x001560B84F0FULL), "fbsdboot", "FreeBSD Boot"},{UU(0x516E7CB4,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsddata", "FreeBSD Data"},{UU(0x516E7CB5,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdswap", "FreeBSD Swap"},{UU(0x516E7CB6,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdufs", "FreeBSD Unix File System"},{UU(0x516E7CB8,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdvvm", "FreeBSD Vinum volume manager"},{UU(0x516E7CBA,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdzfs", "FreeBSD ZFS"},{UU(0x48465300,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "applehfs", "Apple HFS+"},{UU(0x55465300,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "appleufs", "Apple UFS"},{UU(0x6A898CC3,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "applezfs", "Apple ZFS"},{UU(0x52414944,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "appleraid", "Apple RAID"},{UU(0x52414944,0x5F4F,0x11AA,0xAA11,0x00306543ECACULL), "appleraidoff", "Apple RAID, offline"},{UU(0x426F6F74,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "appleboot", "Apple Boot"},{UU(0x4C616265,0x6C00,0x11AA,0xAA11,0x00306543ECACULL), "applelabel", "Apple Label"},{UU(0x5265636F,0x7665,0x11AA,0xAA11,0x00306543ECACULL), "appletv", "Apple TV Recovery"},{UU(0x53746F72,0x6167,0x11AA,0xAA11,0x00306543ECACULL), "applecs", "Apple Core Storage"},{UU(0x6A82CB45,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisboot", "Solaris Boot"},{UU(0x6A85CF4D,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisroot", "Solaris Root"},{UU(0x6A87C46F,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisswap", "Solaris Swap"},{UU(0x6A8B642B,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisbackup", "Solaris Backup"},{UU(0x6A898CC3,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisusr", "Solaris /usr"},{UU(0x6A8EF2E9,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisvar", "Solaris /var"},{UU(0x6A90BA39,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarishome", "Solaris /home"},{UU(0x6A9283A5,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisalt", "Solaris Alternate sector"},{UU(0x6A945A3B,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"},{UU(0x6A9630D1,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"},{UU(0x6A980767,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"},{UU(0x6A96237F,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"},{UU(0x6A8D2AC7,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"},{UU(0x49F48D32,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdswap", "NetBSD Swap"},{UU(0x49F48D5A,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdffs", "NetBSD FFS"},{UU(0x49F48D82,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdlfs", "NetBSD LFS"},{UU(0x49F48DAA,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdraid", "NetBSD RAID"},{UU(0x2DB519C4,0xB10F,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdcat", "NetBSD Concatenated"},{UU(0x2DB519EC,0xB10F,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdcrypt", "NetBSD Encrypted"},{UU(0xFE3A2A5D,0x4F32,0x41A7,0xB725,0xACCC3285A309ULL), "chromeoskern", "ChromeOS kernel"},{UU(0x3CB8E202,0x3B7E,0x47DD,0x8A3C,0x7FF2A13CFCECULL), "chromeosroot", "ChromeOS rootfs"},{UU(0x2E0A753D,0x9E48,0x43B0,0x8337,0xB15192CB1B5EULL), "chromeos", "ChromeOS future use"},{UU(0x42465331,0x3BA3,0x10F1,0x802A,0x4861696B7521ULL), "haikubfs", "Haiku BFS"},{UU(0x85D5E45E,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdboot", "MidnightBSD Boot"},{UU(0x85D5E45A,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsddata", "MidnightBSD Data"},{UU(0x85D5E45B,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdswap", "MidnightBSD Swap"},{UU(0x0394EF8B,0x237E,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdufs", "MidnightBSD Unix File System"},{UU(0x85D5E45C,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdvvm", "MidnightBSD Vinum volume manager"},{UU(0x85D5E45D,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdzfs", "MidnightBSD ZFS"},{UU(0x45B0969E,0x9B03,0x4F30,0xB4C6,0xB4B80CEFF106ULL), "cephjournal", "Ceph Journal"},{UU(0x45B0969E,0x9B03,0x4F30,0xB4C6,0x5EC00CEFF106ULL), "cephcrypt", "Ceph dm-crypt Encrypted Journal"},{UU(0x4FBD7E29,0x9D25,0x41B8,0xAFD0,0x062C0CEFF05DULL), "cephosd", "Ceph OSD"},{UU(0x4FBD7E29,0x9D25,0x41B8,0xAFD0,0x5EC00CEFF05DULL), "cephcryptosd", "Ceph dm-crypt OSD"},{UU(0x824CC7A0,0x36A8,0x11E3,0x890A,0x952519AD3F61ULL), "openbsd", "OpenBSD Data"},{UU(0xCEF5A9AD,0x73BC,0x4601,0x89F3,0xCDEEEEE321A1ULL), "qnx6", "QNX6 Power-safe file system"},{UU(0xC91818F9,0x8025,0x47AF,0x89D2,0xF030D7000C2CULL), "plan9", "Plan 9"},{UU(0x9D275380,0x40AD,0x11DB,0xBF97,0x000C2911D1B8ULL), "vmwareesxcore", "VMware ESX vmkcore (coredump)"},{UU(0xAA31E02A,0x400F,0x11DB,0x9590,0x000C2911D1B8ULL), "vmwareesxvmfs", "VMware ESX VMFS filesystem"},{UU(0x9198EFFC,0x31C0,0x11DB,0x8F78,0x000C2911D1B8ULL), "vmwareesxrsv", "VMware ESX reserved"},{UU(0x2568845D,0x2332,0x4675,0xBC39,0x8FA5A4748D15ULL), "androidiabootloader", "Android-IA Bootloader"},{UU(0x114EAFFE,0x1552,0x4022,0xB26E,0x9B053604CF84ULL), "androidiabootloader2", "Android-IA Bootloader 2"},{UU(0x49A4D17F,0x93A3,0x45C1,0xA0DE,0xF50B2EBE2599ULL), "androidiaboot", "Android-IA Boot"},{UU(0x4177C722,0x9E92,0x4AAB,0x8644,0x43502BFD5506ULL), "androidiarecovery", "Android-IA Recovery"},{UU(0xEF32A33B,0xA409,0x486C,0x9141,0x9FFB711F6266ULL), "androidiamisc", "Android-IA Misc"},{UU(0x20AC26BE,0x20B7,0x11E3,0x84C5,0x6CFDB94711E9ULL), "androidiametadata", "Android-IA Metadata"},{UU(0x38F428E6,0xD326,0x425D,0x9140,0x6E0EA133647CULL), "androidiasystem", "Android-IA System"},{UU(0xA893EF21,0xE428,0x470A,0x9E55,0x0668FD91A2D9ULL), "androidiacache", "Android-IA Cache"},{UU(0xDC76DDA9,0x5AC1,0x491C,0xAF42,0xA82591580C0DULL), "androidiadata", "Android-IA Data"},{UU(0xEBC597D0,0x2053,0x4B15,0x8B64,0xE0AAC75F4DB1ULL), "androidiapersistent", "Android-IA Persistent"},{UU(0x8F68CC74,0xC5E5,0x48DA,0xBE91,0xA0C8C15E9C80ULL), "androidiafactory", "Android-IA Factory"},{UU(0x767941D0,0x2085,0x11E3,0xAD3B,0x6CFDB94711E9ULL), "androidiafastboot", "Android-IA Fastboot"},{UU(0xAC6D7924,0xEB71,0x4DF8,0xB48D,0xE267B27148FFULL), "androidiaoem", "Android-IA OEM"},{UU(0x7412F7D5,0xA156,0x4B13,0x81DC,0x867174929325ULL), "onieboot", "ONIE boot"},{UU(0xD4E6E2CD,0x4469,0x46F3,0xB5CB,0x1BFF57AFC149ULL), "onieconfig", "ONIE configuration"},{UU(0x9E1A2D38,0xC612,0x4316,0xAA26,0x8B49521E5A8BULL), "powerpcprep", "PowerPC PReP boot"},{UU(0xBC13C2FF,0x59E6,0x4262,0xA352,0xB275FD6F7172ULL), "freedesktopos", "Freedesktop shared boot loader configuration"},{UU(0x734E5AFE,0xF61A,0x11E6,0xBC64,0x92361F002671ULL), "ataritos", "Atari TOS"},}; static Flag flags[] = { { 0x0000000000000001ULL, 'S', "system" }, { 0x0000000000000002ULL, 'E', "efi-hidden" }, { 0x0000000000000004ULL, 'A', "active" }, { 0x2000000000000000ULL, 'R', "read-only" }, { 0x4000000000000000ULL, 'H', "hidden" }, { 0x8000000000000000ULL, 'M', "nomount" }, { 0, 0, nil }}; static void initcrc32(void);static u32int sumcrc32(u32int, uchar *, ulong); static u32int getle32(void*);static void putle32(void*, u32int);static u64int getle64(void *);static void putle64(void *, u64int); static void uugen(uchar uuid[16]);static Type* gettype(uchar uuid[16], char *name);static int uufmt(Fmt*);#pragma varargck type "U" uchar* static int attrfmt(Fmt*);#pragma varargck type "A" uvlong static void rdpart(Edit*);static void autopart(Edit*);static void blankpart(Edit*);static void cmdnamectl(Edit*); static int blank;static int dowrite;static int file;static int rdonly;static int doauto;static int printflag;static int written; static void cmdsum(Edit*, Part*, vlong, vlong);static char *cmdadd(Edit*, char*, vlong, vlong);static char *cmddel(Edit*, Part*);static char *cmdext(Edit*, int, char**);static char *cmdhelp(Edit*);static char *cmdokname(Edit*, char*);static char *cmdwrite(Edit*);static void cmdprintctl(Edit*, int); Edit edit = { .add = cmdadd, .del = cmddel, .ext = cmdext, .help = cmdhelp, .okname = cmdokname, .sum = cmdsum, .write = cmdwrite, .printctl = cmdprintctl, .unit = "sector",}; voidusage(void){ fprint(2, "usage: disk/edisk [-abfprw] [-s sectorsize] /dev/sdC0/data\n"); exits("usage");} voidmain(int argc, char **argv){ vlong secsize; fmtinstall('U', uufmt); fmtinstall('A', attrfmt); initcrc32(); secsize = 0; ARGBEGIN{ case 'a': doauto++; break; case 'b': blank++; break; case 'f': file++; break; case 'p': printflag++; break; case 'r': rdonly++; break; case 's': secsize = atoi(ARGF()); break; case 'v': break; case 'w': dowrite++; break; }ARGEND; if(argc != 1) usage(); edit.disk = opendisk(argv[0], rdonly, file); if(edit.disk == nil) { fprint(2, "cannot open disk: %r\n"); exits("opendisk"); } if(secsize != 0) { edit.disk->secsize = secsize; edit.disk->secs = edit.disk->size / secsize; } edit.unitsz = edit.disk->secsize; edit.end = edit.disk->secs; if(blank) blankpart(&edit); else rdpart(&edit); if(doauto) autopart(&edit); if(dowrite) runcmd(&edit, "w"); if(printflag) runcmd(&edit, "P"); if(dowrite || printflag) exits(0); runcmd(&edit, "p"); for(;;) { fprint(2, ">>> "); runcmd(&edit, getline(&edit)); }} typedef struct Block Block;struct Block{ Block *link; Disk *disk; uchar *save; /* saved backup data */ vlong addr; uchar data[];}; static Block *blocks; static void*getblock(Disk *disk, vlong addr){ Block *b; if(addr < 0 || addr >= disk->secs) abort(); for(b = blocks; b != nil; b = b->link){ if(b->addr == addr && b->disk == disk) return b->data; } b = malloc(sizeof(Block) + 2*disk->secsize); if(pread(disk->fd, b->data, disk->secsize, disk->secsize*addr) != disk->secsize) sysfatal("getblock %llud: %r", addr); b->save = &b->data[disk->secsize]; memmove(b->save, b->data, disk->secsize); b->addr = addr; b->link = blocks; b->disk = disk; blocks = b; return b->data;} static voidflushdisk(Disk *disk){ Block *b, *r; if(disk->wfd < 0) return; for(b = blocks; b != nil; b = b->link){ if(b->disk != disk || memcmp(b->data, b->save, disk->secsize) == 0) continue; if(pwrite(disk->wfd, b->data, disk->secsize, b->addr*disk->secsize) != disk->secsize){ fprint(2, "error writing lba %llud: %r\n", b->addr); goto Recover; } } return; Recover: for(r = blocks; r != b; r = r->link){ if(r->disk != disk || memcmp(r->data, r->save, disk->secsize) == 0) continue; pwrite(disk->wfd, r->save, disk->secsize, r->addr*disk->secsize); } exits("recovered");} static u32int crc32tab[256]; static voidinitcrc32(void){ u32int c; int n, k; for(n = 0; n < 256; n++){ c = n; for(k = 0; k < 8; k++) if((c & 1) != 0) c = 0xedb88320 ^ c >> 1; else c >>= 1; crc32tab[n] = c; }}static u32intsumcrc32(u32int c, uchar *buf, ulong len){ c = ~c; while(len-- != 0) c = crc32tab[(*buf++ ^ c) & 0xff] ^ c >> 8; return ~c;} static u32intgetle32(void* v){ uchar *p; p = v; return (p[3]<<24)|(p[2]<<16)|(p[1]<<8)|p[0];} static voidputle32(void* v, u32int i){ uchar *p; p = v; p[0] = i; p[1] = i>>8; p[2] = i>>16; p[3] = i>>24;} static u64intgetle64(void *v){ return ((u64int)getle32((uchar*)v + 4) << 32) | getle32(v);} static voidputle64(void *v, u64int i){ putle32(v, i); putle32((uchar*)v + 4, i >> 32);} static voiduugen(uchar uu[16]){ genrandom(uu, 16); uu[7] = (uu[7] & ~0xF0) | 0x40; uu[8] = (uu[8] & ~0xC0) | 0x80;} static intuufmt(Fmt *fmt){ uchar *uu = va_arg(fmt->args, uchar*); return fmtprint(fmt, "%.2uX%.2uX%.2uX%.2uX-" "%.2uX%.2uX-" "%.2uX%.2uX-" "%.2uX%.2uX-%.2uX%.2uX%.2uX%.2uX%.2uX%.2uX",/* Data1 */ uu[3], uu[2], uu[1], uu[0], /* Data2 */ uu[5], uu[4],/* Data3 */ uu[7], uu[6],/* Data4 */ uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);} static intattrfmt(Fmt *fmt){Lines 1–500 of 1285. Load more
/* * edisk - edit gpt disk partition table */ #include <u.h> #include <libc.h> #include <bio.h> #include <ctype.h> #include <disk.h> #include "edit.h" #include <mp.h> #include <libsec.h> #define TB (1024LL*GB) #define GB (1024*1024*1024) #define MB (1024*1024) #define KB (1024) typedef struct Header Header; typedef struct Entry Entry; typedef struct Type Type; typedef struct Flag Flag; typedef struct Gptpart Gptpart; struct Header { uchar sig[8]; uchar rev[4]; uchar hdrsiz[4]; uchar hdrcrc[4]; uchar zero[4]; uchar selflba[8]; uchar backlba[8]; uchar firstlba[8]; uchar lastlba[8]; uchar devid[16]; uchar tablba[8]; uchar entrycount[4]; uchar entrysize[4]; uchar tabcrc[4]; }; struct Entry { uchar typeid[16]; uchar partid[16]; uchar firstlba[8]; uchar lastlba[8]; uchar attr[8]; uchar name[72]; }; enum { Headersiz = 92, Entrysiz = 16+16+8+8+8+72, }; struct Type { uchar uuid[16]; char *name; char *desc; }; struct Flag { uvlong f; char c; char *desc; }; struct Gptpart { Part; Type *type; /* nil when not in use */ uvlong attr; uchar uuid[16]; Rune label[72+1]; char namebuf[8]; }; static uchar *pmbr; static Header *phdr; static Header *bhdr; static vlong partoff; static vlong partend; static Gptpart *parts; static int nparts; static uchar devid[16]; static uchar zeros[16]; /* RFC4122, but in little endian format */ #define UU(a,b,c,d,e) { \ (a)&255,((a)>>8)&255,((a)>>16)&255,((a)>>24)&255, \ (b)&255,((b)>>8)&255, \ (c)&255,((c)>>8)&255, \ ((d)>>8)&255,(d)&255, \ ((e)>>40)&255, ((e)>>32)&255, ((e)>>24)&255, ((e)>>16)&255, ((e)>>8)&255, (e)&255} static Type types[256] = { {UU(0x00000000,0x0000,0x0000,0x0000,0x000000000000ULL), "", "Unused entry"}, {UU(0x024DEE41,0x33E7,0x11D3,0x9D69,0x0008C781F39FULL), "mbr", "MBR partition"}, {UU(0xC12A7328,0xF81F,0x11D2,0xBA4B,0x00A0C93EC93BULL), "esp", "EFI System Partition"}, {UU(0x21686148,0x6449,0x6E6F,0x744E,0x656564454649ULL), "bios", "BIOS boot partition"}, {UU(0xD3BFE2DE,0x3DAF,0x11DF,0xBA40,0xE3A556D89593ULL), "iffs", "Intel Fast Flash"}, {UU(0xF4019732,0x066E,0x4E12,0x8273,0x346C5641494FULL), "sony", "Sony boot"}, {UU(0xBFBFAFE7,0xA34F,0x448A,0x9A5B,0x6213EB736C22ULL), "lenovo", "Lenovo boot"}, {UU(0xE3C9E316,0x0B5C,0x4DB8,0x817D,0xF92DF00215AEULL), "msr", "Microsoft Reserved Partition"}, {UU(0xEBD0A0A2,0xB9E5,0x4433,0x87C0,0x68B6B72699C7ULL), "dos", "Microsoft Basic data"}, {UU(0x5808C8AA,0x7E8F,0x42E0,0x85D2,0xE1E90434CFB3ULL), "ldmm", "Logical Disk Manager metadata"}, {UU(0xAF9B60A0,0x1431,0x4F62,0xBC68,0x3311714A69ADULL), "ldmd", "Logical Disk Manager data"}, {UU(0xDE94BBA4,0x06D1,0x4D40,0xA16A,0xBFD50179D6ACULL), "recovery", "Windows Recovery Environment"}, {UU(0x37AFFC90,0xEF7D,0x4E96,0x91C3,0x2D7AE055B174ULL), "gpfs", "IBM General Parallel File System"}, {UU(0xE75CAF8F,0xF680,0x4CEE,0xAFA3,0xB001E56EFC2DULL), "storagespaces", "Storage Spaces"}, {UU(0x75894C1E,0x3AEB,0x11D3,0xB7C1,0x7B03A0000000ULL), "hpuxdata", "HP-UX Data"}, {UU(0xE2A1E728,0x32E3,0x11D6,0xA682,0x7B03A0000000ULL), "hpuxserv", "HP-UX Service"}, {UU(0x0FC63DAF,0x8483,0x4772,0x8E79,0x3D69D8477DE4ULL), "linuxdata", "Linux Data"}, {UU(0xA19D880F,0x05FC,0x4D3B,0xA006,0x743F0F84911EULL), "linuxraid", "Linux RAID"}, {UU(0x0657FD6D,0xA4AB,0x43C4,0x84E5,0x0933C84B4F4FULL), "linuxswap", "Linux Swap"}, {UU(0xE6D6D379,0xF507,0x44C2,0xA23C,0x238F2A3DF928ULL), "linuxlvm", "Linux Logical Volume Manager"}, {UU(0x933AC7E1,0x2EB4,0x4F13,0xB844,0x0E14E2AEF915ULL), "linuxhome", "Linux /home"}, {UU(0x3B8F8425,0x20E0,0x4F3B,0x907F,0x1A25A76F98E8ULL), "linuxsrv", "Linux /srv"}, {UU(0x7FFEC5C9,0x2D00,0x49B7,0x8941,0x3EA10A5586B7ULL), "linuxcrypt", "Linux Plain dm-crypt"}, {UU(0xCA7D7CCB,0x63ED,0x4C53,0x861C,0x1742536059CCULL), "luks", "LUKS"}, {UU(0x8DA63339,0x0007,0x60C0,0xC436,0x083AC8230908ULL), "linuxreserved", "Linux Reserved"}, {UU(0x83BD6B9D,0x7F41,0x11DC,0xBE0B,0x001560B84F0FULL), "fbsdboot", "FreeBSD Boot"}, {UU(0x516E7CB4,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsddata", "FreeBSD Data"}, {UU(0x516E7CB5,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdswap", "FreeBSD Swap"}, {UU(0x516E7CB6,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdufs", "FreeBSD Unix File System"}, {UU(0x516E7CB8,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdvvm", "FreeBSD Vinum volume manager"}, {UU(0x516E7CBA,0x6ECF,0x11D6,0x8FF8,0x00022D09712BULL), "fbsdzfs", "FreeBSD ZFS"}, {UU(0x48465300,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "applehfs", "Apple HFS+"}, {UU(0x55465300,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "appleufs", "Apple UFS"}, {UU(0x6A898CC3,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "applezfs", "Apple ZFS"}, {UU(0x52414944,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "appleraid", "Apple RAID"}, {UU(0x52414944,0x5F4F,0x11AA,0xAA11,0x00306543ECACULL), "appleraidoff", "Apple RAID, offline"}, {UU(0x426F6F74,0x0000,0x11AA,0xAA11,0x00306543ECACULL), "appleboot", "Apple Boot"}, {UU(0x4C616265,0x6C00,0x11AA,0xAA11,0x00306543ECACULL), "applelabel", "Apple Label"}, {UU(0x5265636F,0x7665,0x11AA,0xAA11,0x00306543ECACULL), "appletv", "Apple TV Recovery"}, {UU(0x53746F72,0x6167,0x11AA,0xAA11,0x00306543ECACULL), "applecs", "Apple Core Storage"}, {UU(0x6A82CB45,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisboot", "Solaris Boot"}, {UU(0x6A85CF4D,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisroot", "Solaris Root"}, {UU(0x6A87C46F,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisswap", "Solaris Swap"}, {UU(0x6A8B642B,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisbackup", "Solaris Backup"}, {UU(0x6A898CC3,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisusr", "Solaris /usr"}, {UU(0x6A8EF2E9,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisvar", "Solaris /var"}, {UU(0x6A90BA39,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarishome", "Solaris /home"}, {UU(0x6A9283A5,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solarisalt", "Solaris Alternate sector"}, {UU(0x6A945A3B,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"}, {UU(0x6A9630D1,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"}, {UU(0x6A980767,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"}, {UU(0x6A96237F,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"}, {UU(0x6A8D2AC7,0x1DD2,0x11B2,0x99A6,0x080020736631ULL), "solaris", "Solaris Reserved"}, {UU(0x49F48D32,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdswap", "NetBSD Swap"}, {UU(0x49F48D5A,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdffs", "NetBSD FFS"}, {UU(0x49F48D82,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdlfs", "NetBSD LFS"}, {UU(0x49F48DAA,0xB10E,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdraid", "NetBSD RAID"}, {UU(0x2DB519C4,0xB10F,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdcat", "NetBSD Concatenated"}, {UU(0x2DB519EC,0xB10F,0x11DC,0xB99B,0x0019D1879648ULL), "nbsdcrypt", "NetBSD Encrypted"}, {UU(0xFE3A2A5D,0x4F32,0x41A7,0xB725,0xACCC3285A309ULL), "chromeoskern", "ChromeOS kernel"}, {UU(0x3CB8E202,0x3B7E,0x47DD,0x8A3C,0x7FF2A13CFCECULL), "chromeosroot", "ChromeOS rootfs"}, {UU(0x2E0A753D,0x9E48,0x43B0,0x8337,0xB15192CB1B5EULL), "chromeos", "ChromeOS future use"}, {UU(0x42465331,0x3BA3,0x10F1,0x802A,0x4861696B7521ULL), "haikubfs", "Haiku BFS"}, {UU(0x85D5E45E,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdboot", "MidnightBSD Boot"}, {UU(0x85D5E45A,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsddata", "MidnightBSD Data"}, {UU(0x85D5E45B,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdswap", "MidnightBSD Swap"}, {UU(0x0394EF8B,0x237E,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdufs", "MidnightBSD Unix File System"}, {UU(0x85D5E45C,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdvvm", "MidnightBSD Vinum volume manager"}, {UU(0x85D5E45D,0x237C,0x11E1,0xB4B3,0xE89A8F7FC3A7ULL), "midbsdzfs", "MidnightBSD ZFS"}, {UU(0x45B0969E,0x9B03,0x4F30,0xB4C6,0xB4B80CEFF106ULL), "cephjournal", "Ceph Journal"}, {UU(0x45B0969E,0x9B03,0x4F30,0xB4C6,0x5EC00CEFF106ULL), "cephcrypt", "Ceph dm-crypt Encrypted Journal"}, {UU(0x4FBD7E29,0x9D25,0x41B8,0xAFD0,0x062C0CEFF05DULL), "cephosd", "Ceph OSD"}, {UU(0x4FBD7E29,0x9D25,0x41B8,0xAFD0,0x5EC00CEFF05DULL), "cephcryptosd", "Ceph dm-crypt OSD"}, {UU(0x824CC7A0,0x36A8,0x11E3,0x890A,0x952519AD3F61ULL), "openbsd", "OpenBSD Data"}, {UU(0xCEF5A9AD,0x73BC,0x4601,0x89F3,0xCDEEEEE321A1ULL), "qnx6", "QNX6 Power-safe file system"}, {UU(0xC91818F9,0x8025,0x47AF,0x89D2,0xF030D7000C2CULL), "plan9", "Plan 9"}, {UU(0x9D275380,0x40AD,0x11DB,0xBF97,0x000C2911D1B8ULL), "vmwareesxcore", "VMware ESX vmkcore (coredump)"}, {UU(0xAA31E02A,0x400F,0x11DB,0x9590,0x000C2911D1B8ULL), "vmwareesxvmfs", "VMware ESX VMFS filesystem"}, {UU(0x9198EFFC,0x31C0,0x11DB,0x8F78,0x000C2911D1B8ULL), "vmwareesxrsv", "VMware ESX reserved"}, {UU(0x2568845D,0x2332,0x4675,0xBC39,0x8FA5A4748D15ULL), "androidiabootloader", "Android-IA Bootloader"}, {UU(0x114EAFFE,0x1552,0x4022,0xB26E,0x9B053604CF84ULL), "androidiabootloader2", "Android-IA Bootloader 2"}, {UU(0x49A4D17F,0x93A3,0x45C1,0xA0DE,0xF50B2EBE2599ULL), "androidiaboot", "Android-IA Boot"}, {UU(0x4177C722,0x9E92,0x4AAB,0x8644,0x43502BFD5506ULL), "androidiarecovery", "Android-IA Recovery"}, {UU(0xEF32A33B,0xA409,0x486C,0x9141,0x9FFB711F6266ULL), "androidiamisc", "Android-IA Misc"}, {UU(0x20AC26BE,0x20B7,0x11E3,0x84C5,0x6CFDB94711E9ULL), "androidiametadata", "Android-IA Metadata"}, {UU(0x38F428E6,0xD326,0x425D,0x9140,0x6E0EA133647CULL), "androidiasystem", "Android-IA System"}, {UU(0xA893EF21,0xE428,0x470A,0x9E55,0x0668FD91A2D9ULL), "androidiacache", "Android-IA Cache"}, {UU(0xDC76DDA9,0x5AC1,0x491C,0xAF42,0xA82591580C0DULL), "androidiadata", "Android-IA Data"}, {UU(0xEBC597D0,0x2053,0x4B15,0x8B64,0xE0AAC75F4DB1ULL), "androidiapersistent", "Android-IA Persistent"}, {UU(0x8F68CC74,0xC5E5,0x48DA,0xBE91,0xA0C8C15E9C80ULL), "androidiafactory", "Android-IA Factory"}, {UU(0x767941D0,0x2085,0x11E3,0xAD3B,0x6CFDB94711E9ULL), "androidiafastboot", "Android-IA Fastboot"}, {UU(0xAC6D7924,0xEB71,0x4DF8,0xB48D,0xE267B27148FFULL), "androidiaoem", "Android-IA OEM"}, {UU(0x7412F7D5,0xA156,0x4B13,0x81DC,0x867174929325ULL), "onieboot", "ONIE boot"}, {UU(0xD4E6E2CD,0x4469,0x46F3,0xB5CB,0x1BFF57AFC149ULL), "onieconfig", "ONIE configuration"}, {UU(0x9E1A2D38,0xC612,0x4316,0xAA26,0x8B49521E5A8BULL), "powerpcprep", "PowerPC PReP boot"}, {UU(0xBC13C2FF,0x59E6,0x4262,0xA352,0xB275FD6F7172ULL), "freedesktopos", "Freedesktop shared boot loader configuration"}, {UU(0x734E5AFE,0xF61A,0x11E6,0xBC64,0x92361F002671ULL), "ataritos", "Atari TOS"}, }; static Flag flags[] = { { 0x0000000000000001ULL, 'S', "system" }, { 0x0000000000000002ULL, 'E', "efi-hidden" }, { 0x0000000000000004ULL, 'A', "active" }, { 0x2000000000000000ULL, 'R', "read-only" }, { 0x4000000000000000ULL, 'H', "hidden" }, { 0x8000000000000000ULL, 'M', "nomount" }, { 0, 0, nil } }; static void initcrc32(void); static u32int sumcrc32(u32int, uchar *, ulong); static u32int getle32(void*); static void putle32(void*, u32int); static u64int getle64(void *); static void putle64(void *, u64int); static void uugen(uchar uuid[16]); static Type* gettype(uchar uuid[16], char *name); static int uufmt(Fmt*); #pragma varargck type "U" uchar* static int attrfmt(Fmt*); #pragma varargck type "A" uvlong static void rdpart(Edit*); static void autopart(Edit*); static void blankpart(Edit*); static void cmdnamectl(Edit*); static int blank; static int dowrite; static int file; static int rdonly; static int doauto; static int printflag; static int written; static void cmdsum(Edit*, Part*, vlong, vlong); static char *cmdadd(Edit*, char*, vlong, vlong); static char *cmddel(Edit*, Part*); static char *cmdext(Edit*, int, char**); static char *cmdhelp(Edit*); static char *cmdokname(Edit*, char*); static char *cmdwrite(Edit*); static void cmdprintctl(Edit*, int); Edit edit = { .add = cmdadd, .del = cmddel, .ext = cmdext, .help = cmdhelp, .okname = cmdokname, .sum = cmdsum, .write = cmdwrite, .printctl = cmdprintctl, .unit = "sector", }; void usage(void) { fprint(2, "usage: disk/edisk [-abfprw] [-s sectorsize] /dev/sdC0/data\n"); exits("usage"); } void main(int argc, char **argv) { vlong secsize; fmtinstall('U', uufmt); fmtinstall('A', attrfmt); initcrc32(); secsize = 0; ARGBEGIN{ case 'a': doauto++; break; case 'b': blank++; break; case 'f': file++; break; case 'p': printflag++; break; case 'r': rdonly++; break; case 's': secsize = atoi(ARGF()); break; case 'v': break; case 'w': dowrite++; break; }ARGEND; if(argc != 1) usage(); edit.disk = opendisk(argv[0], rdonly, file); if(edit.disk == nil) { fprint(2, "cannot open disk: %r\n"); exits("opendisk"); } if(secsize != 0) { edit.disk->secsize = secsize; edit.disk->secs = edit.disk->size / secsize; } edit.unitsz = edit.disk->secsize; edit.end = edit.disk->secs; if(blank) blankpart(&edit); else rdpart(&edit); if(doauto) autopart(&edit); if(dowrite) runcmd(&edit, "w"); if(printflag) runcmd(&edit, "P"); if(dowrite || printflag) exits(0); runcmd(&edit, "p"); for(;;) { fprint(2, ">>> "); runcmd(&edit, getline(&edit)); } } typedef struct Block Block; struct Block { Block *link; Disk *disk; uchar *save; /* saved backup data */ vlong addr; uchar data[]; }; static Block *blocks; static void* getblock(Disk *disk, vlong addr) { Block *b; if(addr < 0 || addr >= disk->secs) abort(); for(b = blocks; b != nil; b = b->link){ if(b->addr == addr && b->disk == disk) return b->data; } b = malloc(sizeof(Block) + 2*disk->secsize); if(pread(disk->fd, b->data, disk->secsize, disk->secsize*addr) != disk->secsize) sysfatal("getblock %llud: %r", addr); b->save = &b->data[disk->secsize]; memmove(b->save, b->data, disk->secsize); b->addr = addr; b->link = blocks; b->disk = disk; blocks = b; return b->data; } static void flushdisk(Disk *disk) { Block *b, *r; if(disk->wfd < 0) return; for(b = blocks; b != nil; b = b->link){ if(b->disk != disk || memcmp(b->data, b->save, disk->secsize) == 0) continue; if(pwrite(disk->wfd, b->data, disk->secsize, b->addr*disk->secsize) != disk->secsize){ fprint(2, "error writing lba %llud: %r\n", b->addr); goto Recover; } } return; Recover: for(r = blocks; r != b; r = r->link){ if(r->disk != disk || memcmp(r->data, r->save, disk->secsize) == 0) continue; pwrite(disk->wfd, r->save, disk->secsize, r->addr*disk->secsize); } exits("recovered"); } static u32int crc32tab[256]; static void initcrc32(void) { u32int c; int n, k; for(n = 0; n < 256; n++){ c = n; for(k = 0; k < 8; k++) if((c & 1) != 0) c = 0xedb88320 ^ c >> 1; else c >>= 1; crc32tab[n] = c; } } static u32int sumcrc32(u32int c, uchar *buf, ulong len) { c = ~c; while(len-- != 0) c = crc32tab[(*buf++ ^ c) & 0xff] ^ c >> 8; return ~c; } static u32int getle32(void* v) { uchar *p; p = v; return (p[3]<<24)|(p[2]<<16)|(p[1]<<8)|p[0]; } static void putle32(void* v, u32int i) { uchar *p; p = v; p[0] = i; p[1] = i>>8; p[2] = i>>16; p[3] = i>>24; } static u64int getle64(void *v) { return ((u64int)getle32((uchar*)v + 4) << 32) | getle32(v); } static void putle64(void *v, u64int i) { putle32(v, i); putle32((uchar*)v + 4, i >> 32); } static void uugen(uchar uu[16]) { genrandom(uu, 16); uu[7] = (uu[7] & ~0xF0) | 0x40; uu[8] = (uu[8] & ~0xC0) | 0x80; } static int uufmt(Fmt *fmt) { uchar *uu = va_arg(fmt->args, uchar*); return fmtprint(fmt, "%.2uX%.2uX%.2uX%.2uX-" "%.2uX%.2uX-" "%.2uX%.2uX-" "%.2uX%.2uX-%.2uX%.2uX%.2uX%.2uX%.2uX%.2uX", /* Data1 */ uu[3], uu[2], uu[1], uu[0], /* Data2 */ uu[5], uu[4], /* Data3 */ uu[7], uu[6], /* Data4 */ uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); } static int attrfmt(Fmt *fmt) {