17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*d1a180b0Smaheshvs * Common Development and Distribution License (the "License"). 6*d1a180b0Smaheshvs * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 226451fdbcSvsakar * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 317c478bd9Sstevel@tonic-gate * The Regents of the University of California 327c478bd9Sstevel@tonic-gate * All Rights Reserved 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 357c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 367c478bd9Sstevel@tonic-gate * contributors. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /* 427c478bd9Sstevel@tonic-gate * Label a file system volume. 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #include <stdio.h> 467c478bd9Sstevel@tonic-gate #include <string.h> 477c478bd9Sstevel@tonic-gate #include <stdlib.h> 487c478bd9Sstevel@tonic-gate #include <unistd.h> 497c478bd9Sstevel@tonic-gate #include <sys/param.h> 507c478bd9Sstevel@tonic-gate #include <sys/types.h> 517c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 527c478bd9Sstevel@tonic-gate #include <locale.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #define bcopy(f, t, n) (void) memcpy(t, f, n) 557c478bd9Sstevel@tonic-gate #define bzero(s, n) memset(s, 0, n) 567c478bd9Sstevel@tonic-gate #define bcmp(s, d, n) memcmp(s, d, n) 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #define index(s, r) strchr(s, r) 597c478bd9Sstevel@tonic-gate #define rindex(s, r) strrchr(s, r) 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 627c478bd9Sstevel@tonic-gate #include <fcntl.h> 637c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_inode.h> 647c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h> 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate static void usage(); 67*d1a180b0Smaheshvs static void label(char *, char *, char *); 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static union sbtag { 707c478bd9Sstevel@tonic-gate char dummy[SBSIZE]; 717c478bd9Sstevel@tonic-gate struct fs sblk; 727c478bd9Sstevel@tonic-gate } sb_un, altsb_un; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #define sblock sb_un.sblk 757c478bd9Sstevel@tonic-gate #define altsblock altsb_un.sblk 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate extern int optind; 787c478bd9Sstevel@tonic-gate extern char *optarg; 797c478bd9Sstevel@tonic-gate 80*d1a180b0Smaheshvs int 81*d1a180b0Smaheshvs main(int argc, char *argv[]) 827c478bd9Sstevel@tonic-gate { 837c478bd9Sstevel@tonic-gate int opt; 847c478bd9Sstevel@tonic-gate char *special = NULL; 857c478bd9Sstevel@tonic-gate char *fsname = NULL; 867c478bd9Sstevel@tonic-gate char *volume = NULL; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, "o:")) != EOF) { 897c478bd9Sstevel@tonic-gate switch (opt) { 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate case 'o': /* specific options (none defined yet) */ 927c478bd9Sstevel@tonic-gate break; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate case '?': 957c478bd9Sstevel@tonic-gate usage(); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate if (optind > (argc - 1)) { 997c478bd9Sstevel@tonic-gate usage(); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate argc -= optind; 1027c478bd9Sstevel@tonic-gate argv = &argv[optind]; 1037c478bd9Sstevel@tonic-gate special = argv[0]; 1047c478bd9Sstevel@tonic-gate if (argc > 1) { 1057c478bd9Sstevel@tonic-gate fsname = argv[1]; 1067c478bd9Sstevel@tonic-gate if (strlen(fsname) > 6) { 1077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1097c478bd9Sstevel@tonic-gate gettext("fsname can not be longer than 6 characters\n")); 1107c478bd9Sstevel@tonic-gate exit(31+1); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate if (argc > 2) { 1147c478bd9Sstevel@tonic-gate volume = argv[2]; 1157c478bd9Sstevel@tonic-gate if (strlen(volume) > 6) { 1167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1177c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1187c478bd9Sstevel@tonic-gate gettext("volume can not be longer than 6 characters\n")); 1197c478bd9Sstevel@tonic-gate exit(31+1); 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate label(special, fsname, volume); 123*d1a180b0Smaheshvs return (0); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate void 1277c478bd9Sstevel@tonic-gate usage() 1287c478bd9Sstevel@tonic-gate { 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1317c478bd9Sstevel@tonic-gate "ufs usage: labelit [-F ufs] [gen opts] special [fsname volume]\n")); 1327c478bd9Sstevel@tonic-gate exit(31+1); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate void 136*d1a180b0Smaheshvs label(char *special, char *fsname, char *volume) 1377c478bd9Sstevel@tonic-gate { 1387c478bd9Sstevel@tonic-gate int f; 1397c478bd9Sstevel@tonic-gate int blk; 1407c478bd9Sstevel@tonic-gate int i; 1417c478bd9Sstevel@tonic-gate char *p; 1427c478bd9Sstevel@tonic-gate offset_t offset; 1437c478bd9Sstevel@tonic-gate struct fs *fsp, *altfsp; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if (fsname == NULL) { 1467c478bd9Sstevel@tonic-gate f = open64(special, O_RDONLY); 1477c478bd9Sstevel@tonic-gate } else { 1487c478bd9Sstevel@tonic-gate f = open64(special, O_RDWR); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate if (f < 0) { 1517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1527c478bd9Sstevel@tonic-gate perror("open"); 1537c478bd9Sstevel@tonic-gate exit(31+1); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate if (llseek(f, (offset_t)SBLOCK * DEV_BSIZE, 0) < 0) { 1567c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1577c478bd9Sstevel@tonic-gate perror("llseek"); 1587c478bd9Sstevel@tonic-gate exit(31+1); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate if (read(f, &sblock, SBSIZE) != SBSIZE) { 1617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1627c478bd9Sstevel@tonic-gate perror("read"); 1637c478bd9Sstevel@tonic-gate exit(31+1); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate if ((sblock.fs_magic != FS_MAGIC) && 1667c478bd9Sstevel@tonic-gate (sblock.fs_magic != MTB_UFS_MAGIC)) { 1677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1687c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1697c478bd9Sstevel@tonic-gate gettext("bad super block magic number\n")); 1707c478bd9Sstevel@tonic-gate exit(31+1); 1717c478bd9Sstevel@tonic-gate } 1726451fdbcSvsakar if ((sblock.fs_magic == FS_MAGIC) && 1736451fdbcSvsakar ((sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2) && 1746451fdbcSvsakar (sblock.fs_version != UFS_VERSION_MIN))) { 1756451fdbcSvsakar (void) fprintf(stderr, gettext("labelit: ")); 1766451fdbcSvsakar (void) fprintf(stderr, 1776451fdbcSvsakar gettext("unrecognized UFS format version: %d\n"), 1786451fdbcSvsakar sblock.fs_version); 1796451fdbcSvsakar exit(31+1); 1806451fdbcSvsakar } 1817c478bd9Sstevel@tonic-gate if ((sblock.fs_magic == MTB_UFS_MAGIC) && 1827c478bd9Sstevel@tonic-gate ((sblock.fs_version > MTB_UFS_VERSION_1) || 1837c478bd9Sstevel@tonic-gate (sblock.fs_version < MTB_UFS_VERSION_MIN))) { 1847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1857c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1867c478bd9Sstevel@tonic-gate gettext("unrecognized UFS format version: %d\n"), 1877c478bd9Sstevel@tonic-gate sblock.fs_version); 1887c478bd9Sstevel@tonic-gate exit(31+1); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate fsp = &sblock; 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate /* 1937c478bd9Sstevel@tonic-gate * Is block layout available? 1947c478bd9Sstevel@tonic-gate */ 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate if (sblock.fs_cpc <= 0 && (fsname || volume)) { 1977c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 1987c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1997c478bd9Sstevel@tonic-gate gettext("insufficient superblock space for file system label\n")); 2007c478bd9Sstevel@tonic-gate return; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate /* 2047c478bd9Sstevel@tonic-gate * calculate the available blocks for each rotational position 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate blk = sblock.fs_spc * sblock.fs_cpc / NSPF(&sblock); 2077c478bd9Sstevel@tonic-gate for (i = 0; i < blk; i += sblock.fs_frag) 2087c478bd9Sstevel@tonic-gate /* void */; 2097c478bd9Sstevel@tonic-gate i -= sblock.fs_frag; 2107c478bd9Sstevel@tonic-gate blk = i / sblock.fs_frag; 2117c478bd9Sstevel@tonic-gate p = (char *)&(fs_rotbl(fsp)[blk]); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate if (fsname != NULL) { 2147c478bd9Sstevel@tonic-gate for (i = 0; i < 14; i++) 2157c478bd9Sstevel@tonic-gate p[i] = '\0'; 2167c478bd9Sstevel@tonic-gate for (i = 0; (i < 6) && (fsname[i]); i++, p++) 2177c478bd9Sstevel@tonic-gate *p = fsname[i]; 2187c478bd9Sstevel@tonic-gate p++; 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate if (volume != NULL) { 2217c478bd9Sstevel@tonic-gate for (i = 0; (i < 6) && (volume[i]); i++, p++) 2227c478bd9Sstevel@tonic-gate *p = volume[i]; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate if (fsname != NULL) { 2257c478bd9Sstevel@tonic-gate if (llseek(f, (offset_t)SBLOCK * DEV_BSIZE, 0) < 0) { 2267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2277c478bd9Sstevel@tonic-gate perror("llseek"); 2287c478bd9Sstevel@tonic-gate exit(31+1); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate if (write(f, &sblock, SBSIZE) != SBSIZE) { 2317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2327c478bd9Sstevel@tonic-gate perror("write"); 2337c478bd9Sstevel@tonic-gate exit(31+1); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate for (i = 0; i < sblock.fs_ncg; i++) { 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * In the case of multi-terabyte ufs file 2387c478bd9Sstevel@tonic-gate * systems, only the first ten and last ten 2397c478bd9Sstevel@tonic-gate * cylinder groups have copies of the superblock. 2407c478bd9Sstevel@tonic-gate */ 2417c478bd9Sstevel@tonic-gate if (sblock.fs_magic == MTB_UFS_MAGIC && 2427c478bd9Sstevel@tonic-gate sblock.fs_ncg > 20 && 2437c478bd9Sstevel@tonic-gate (i >= 10 && i < sblock.fs_ncg - 10)) 2447c478bd9Sstevel@tonic-gate continue; 2457c478bd9Sstevel@tonic-gate offset = 2467c478bd9Sstevel@tonic-gate (offset_t)cgsblock(&sblock, i) * sblock.fs_fsize; 2477c478bd9Sstevel@tonic-gate if (llseek(f, offset, 0) < 0) { 2487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2497c478bd9Sstevel@tonic-gate perror("lseek"); 2507c478bd9Sstevel@tonic-gate exit(31+1); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate altfsp = &altsblock; 2537c478bd9Sstevel@tonic-gate if (read(f, &altsblock, SBSIZE) != SBSIZE) { 2547c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2557c478bd9Sstevel@tonic-gate perror("read"); 2567c478bd9Sstevel@tonic-gate exit(31+1); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate if ((altsblock.fs_magic != FS_MAGIC) && 2597c478bd9Sstevel@tonic-gate (altsblock.fs_magic != MTB_UFS_MAGIC)) { 2607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2627c478bd9Sstevel@tonic-gate gettext("bad alternate super block(%i) magic number\n"), i); 2637c478bd9Sstevel@tonic-gate exit(31+1); 2647c478bd9Sstevel@tonic-gate } 2656451fdbcSvsakar if ((altsblock.fs_magic == FS_MAGIC) && 2666451fdbcSvsakar ((altsblock.fs_version != 2676451fdbcSvsakar UFS_EFISTYLE4NONEFI_VERSION_2) && 2686451fdbcSvsakar (altsblock.fs_version != UFS_VERSION_MIN))) { 2696451fdbcSvsakar (void) fprintf(stderr, gettext("labelit: ")); 2706451fdbcSvsakar (void) fprintf(stderr, 2716451fdbcSvsakar gettext("bad alternate super block UFS format version: %d\n"), 2726451fdbcSvsakar altsblock.fs_version); 2736451fdbcSvsakar exit(31+1); 2746451fdbcSvsakar } 2757c478bd9Sstevel@tonic-gate if ((altsblock.fs_magic == MTB_UFS_MAGIC) && 2767c478bd9Sstevel@tonic-gate ((altsblock.fs_version > MTB_UFS_VERSION_1) || 2777c478bd9Sstevel@tonic-gate (altsblock.fs_version < MTB_UFS_VERSION_MIN))) { 2787c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2807c478bd9Sstevel@tonic-gate gettext("bad alternate super block UFS format version: %d\n"), 2817c478bd9Sstevel@tonic-gate altsblock.fs_version); 2827c478bd9Sstevel@tonic-gate exit(31+1); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate bcopy((char *)&(fs_rotbl(fsp)[blk]), 2857c478bd9Sstevel@tonic-gate (char *)&(fs_rotbl(altfsp)[blk]), 14); 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate if (llseek(f, offset, 0) < 0) { 2887c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2897c478bd9Sstevel@tonic-gate perror("llseek"); 2907c478bd9Sstevel@tonic-gate exit(31+1); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate if (write(f, &altsblock, SBSIZE) != SBSIZE) { 2937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: ")); 2947c478bd9Sstevel@tonic-gate perror("write"); 2957c478bd9Sstevel@tonic-gate exit(31+1); 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate p = (char *)&(fs_rotbl(fsp)[blk]); 3007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fsname: ")); 3017c478bd9Sstevel@tonic-gate for (i = 0; (i < 6) && (*p); i++, p++) { 3027c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%c", *p); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 3057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("volume: ")); 3067c478bd9Sstevel@tonic-gate p++; 3077c478bd9Sstevel@tonic-gate for (i = 0; (i < 6); i++, p++) { 3087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%c", *p); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 3117c478bd9Sstevel@tonic-gate } 312