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 /*
407c478bd9Sstevel@tonic-gate * Label a file system volume.
417c478bd9Sstevel@tonic-gate */
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate #include <stdio.h>
447c478bd9Sstevel@tonic-gate #include <string.h>
457c478bd9Sstevel@tonic-gate #include <stdlib.h>
467c478bd9Sstevel@tonic-gate #include <unistd.h>
477c478bd9Sstevel@tonic-gate #include <sys/param.h>
487c478bd9Sstevel@tonic-gate #include <sys/types.h>
497c478bd9Sstevel@tonic-gate #include <sys/mntent.h>
507c478bd9Sstevel@tonic-gate #include <locale.h>
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate #define bcopy(f, t, n) (void) memcpy(t, f, n)
537c478bd9Sstevel@tonic-gate #define bzero(s, n) memset(s, 0, n)
547c478bd9Sstevel@tonic-gate #define bcmp(s, d, n) memcmp(s, d, n)
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #define index(s, r) strchr(s, r)
577c478bd9Sstevel@tonic-gate #define rindex(s, r) strrchr(s, r)
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
607c478bd9Sstevel@tonic-gate #include <fcntl.h>
617c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_inode.h>
627c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h>
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate static void usage();
65*d1a180b0Smaheshvs static void label(char *, char *, char *);
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate static union sbtag {
687c478bd9Sstevel@tonic-gate char dummy[SBSIZE];
697c478bd9Sstevel@tonic-gate struct fs sblk;
707c478bd9Sstevel@tonic-gate } sb_un, altsb_un;
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate #define sblock sb_un.sblk
737c478bd9Sstevel@tonic-gate #define altsblock altsb_un.sblk
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate extern int optind;
767c478bd9Sstevel@tonic-gate extern char *optarg;
777c478bd9Sstevel@tonic-gate
78*d1a180b0Smaheshvs int
main(int argc,char * argv[])79*d1a180b0Smaheshvs main(int argc, char *argv[])
807c478bd9Sstevel@tonic-gate {
817c478bd9Sstevel@tonic-gate int opt;
827c478bd9Sstevel@tonic-gate char *special = NULL;
837c478bd9Sstevel@tonic-gate char *fsname = NULL;
847c478bd9Sstevel@tonic-gate char *volume = NULL;
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, "o:")) != EOF) {
877c478bd9Sstevel@tonic-gate switch (opt) {
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate case 'o': /* specific options (none defined yet) */
907c478bd9Sstevel@tonic-gate break;
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate case '?':
937c478bd9Sstevel@tonic-gate usage();
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate if (optind > (argc - 1)) {
977c478bd9Sstevel@tonic-gate usage();
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate argc -= optind;
1007c478bd9Sstevel@tonic-gate argv = &argv[optind];
1017c478bd9Sstevel@tonic-gate special = argv[0];
1027c478bd9Sstevel@tonic-gate if (argc > 1) {
1037c478bd9Sstevel@tonic-gate fsname = argv[1];
1047c478bd9Sstevel@tonic-gate if (strlen(fsname) > 6) {
1057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1067c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
1077c478bd9Sstevel@tonic-gate gettext("fsname can not be longer than 6 characters\n"));
1087c478bd9Sstevel@tonic-gate exit(31+1);
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate if (argc > 2) {
1127c478bd9Sstevel@tonic-gate volume = argv[2];
1137c478bd9Sstevel@tonic-gate if (strlen(volume) > 6) {
1147c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1157c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
1167c478bd9Sstevel@tonic-gate gettext("volume can not be longer than 6 characters\n"));
1177c478bd9Sstevel@tonic-gate exit(31+1);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate }
1207c478bd9Sstevel@tonic-gate label(special, fsname, volume);
121*d1a180b0Smaheshvs return (0);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate void
usage()1257c478bd9Sstevel@tonic-gate usage()
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(
1297c478bd9Sstevel@tonic-gate "ufs usage: labelit [-F ufs] [gen opts] special [fsname volume]\n"));
1307c478bd9Sstevel@tonic-gate exit(31+1);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate void
label(char * special,char * fsname,char * volume)134*d1a180b0Smaheshvs label(char *special, char *fsname, char *volume)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate int f;
1377c478bd9Sstevel@tonic-gate int blk;
1387c478bd9Sstevel@tonic-gate int i;
1397c478bd9Sstevel@tonic-gate char *p;
1407c478bd9Sstevel@tonic-gate offset_t offset;
1417c478bd9Sstevel@tonic-gate struct fs *fsp, *altfsp;
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate if (fsname == NULL) {
1447c478bd9Sstevel@tonic-gate f = open64(special, O_RDONLY);
1457c478bd9Sstevel@tonic-gate } else {
1467c478bd9Sstevel@tonic-gate f = open64(special, O_RDWR);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate if (f < 0) {
1497c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1507c478bd9Sstevel@tonic-gate perror("open");
1517c478bd9Sstevel@tonic-gate exit(31+1);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate if (llseek(f, (offset_t)SBLOCK * DEV_BSIZE, 0) < 0) {
1547c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1557c478bd9Sstevel@tonic-gate perror("llseek");
1567c478bd9Sstevel@tonic-gate exit(31+1);
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate if (read(f, &sblock, SBSIZE) != SBSIZE) {
1597c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1607c478bd9Sstevel@tonic-gate perror("read");
1617c478bd9Sstevel@tonic-gate exit(31+1);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate if ((sblock.fs_magic != FS_MAGIC) &&
1647c478bd9Sstevel@tonic-gate (sblock.fs_magic != MTB_UFS_MAGIC)) {
1657c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1667c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
1677c478bd9Sstevel@tonic-gate gettext("bad super block magic number\n"));
1687c478bd9Sstevel@tonic-gate exit(31+1);
1697c478bd9Sstevel@tonic-gate }
1706451fdbcSvsakar if ((sblock.fs_magic == FS_MAGIC) &&
1716451fdbcSvsakar ((sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2) &&
1726451fdbcSvsakar (sblock.fs_version != UFS_VERSION_MIN))) {
1736451fdbcSvsakar (void) fprintf(stderr, gettext("labelit: "));
1746451fdbcSvsakar (void) fprintf(stderr,
1756451fdbcSvsakar gettext("unrecognized UFS format version: %d\n"),
1766451fdbcSvsakar sblock.fs_version);
1776451fdbcSvsakar exit(31+1);
1786451fdbcSvsakar }
1797c478bd9Sstevel@tonic-gate if ((sblock.fs_magic == MTB_UFS_MAGIC) &&
1807c478bd9Sstevel@tonic-gate ((sblock.fs_version > MTB_UFS_VERSION_1) ||
1817c478bd9Sstevel@tonic-gate (sblock.fs_version < MTB_UFS_VERSION_MIN))) {
1827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1837c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
1847c478bd9Sstevel@tonic-gate gettext("unrecognized UFS format version: %d\n"),
1857c478bd9Sstevel@tonic-gate sblock.fs_version);
1867c478bd9Sstevel@tonic-gate exit(31+1);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate fsp = &sblock;
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate * Is block layout available?
1927c478bd9Sstevel@tonic-gate */
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate if (sblock.fs_cpc <= 0 && (fsname || volume)) {
1957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
1967c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
1977c478bd9Sstevel@tonic-gate gettext("insufficient superblock space for file system label\n"));
1987c478bd9Sstevel@tonic-gate return;
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate /*
2027c478bd9Sstevel@tonic-gate * calculate the available blocks for each rotational position
2037c478bd9Sstevel@tonic-gate */
2047c478bd9Sstevel@tonic-gate blk = sblock.fs_spc * sblock.fs_cpc / NSPF(&sblock);
2057c478bd9Sstevel@tonic-gate for (i = 0; i < blk; i += sblock.fs_frag)
2067c478bd9Sstevel@tonic-gate /* void */;
2077c478bd9Sstevel@tonic-gate i -= sblock.fs_frag;
2087c478bd9Sstevel@tonic-gate blk = i / sblock.fs_frag;
2097c478bd9Sstevel@tonic-gate p = (char *)&(fs_rotbl(fsp)[blk]);
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate if (fsname != NULL) {
2127c478bd9Sstevel@tonic-gate for (i = 0; i < 14; i++)
2137c478bd9Sstevel@tonic-gate p[i] = '\0';
2147c478bd9Sstevel@tonic-gate for (i = 0; (i < 6) && (fsname[i]); i++, p++)
2157c478bd9Sstevel@tonic-gate *p = fsname[i];
2167c478bd9Sstevel@tonic-gate p++;
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate if (volume != NULL) {
2197c478bd9Sstevel@tonic-gate for (i = 0; (i < 6) && (volume[i]); i++, p++)
2207c478bd9Sstevel@tonic-gate *p = volume[i];
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate if (fsname != NULL) {
2237c478bd9Sstevel@tonic-gate if (llseek(f, (offset_t)SBLOCK * DEV_BSIZE, 0) < 0) {
2247c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2257c478bd9Sstevel@tonic-gate perror("llseek");
2267c478bd9Sstevel@tonic-gate exit(31+1);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate if (write(f, &sblock, SBSIZE) != SBSIZE) {
2297c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2307c478bd9Sstevel@tonic-gate perror("write");
2317c478bd9Sstevel@tonic-gate exit(31+1);
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate for (i = 0; i < sblock.fs_ncg; i++) {
2347c478bd9Sstevel@tonic-gate /*
2357c478bd9Sstevel@tonic-gate * In the case of multi-terabyte ufs file
2367c478bd9Sstevel@tonic-gate * systems, only the first ten and last ten
2377c478bd9Sstevel@tonic-gate * cylinder groups have copies of the superblock.
2387c478bd9Sstevel@tonic-gate */
2397c478bd9Sstevel@tonic-gate if (sblock.fs_magic == MTB_UFS_MAGIC &&
2407c478bd9Sstevel@tonic-gate sblock.fs_ncg > 20 &&
2417c478bd9Sstevel@tonic-gate (i >= 10 && i < sblock.fs_ncg - 10))
2427c478bd9Sstevel@tonic-gate continue;
2437c478bd9Sstevel@tonic-gate offset =
2447c478bd9Sstevel@tonic-gate (offset_t)cgsblock(&sblock, i) * sblock.fs_fsize;
2457c478bd9Sstevel@tonic-gate if (llseek(f, offset, 0) < 0) {
2467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2477c478bd9Sstevel@tonic-gate perror("lseek");
2487c478bd9Sstevel@tonic-gate exit(31+1);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate altfsp = &altsblock;
2517c478bd9Sstevel@tonic-gate if (read(f, &altsblock, SBSIZE) != SBSIZE) {
2527c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2537c478bd9Sstevel@tonic-gate perror("read");
2547c478bd9Sstevel@tonic-gate exit(31+1);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate if ((altsblock.fs_magic != FS_MAGIC) &&
2577c478bd9Sstevel@tonic-gate (altsblock.fs_magic != MTB_UFS_MAGIC)) {
2587c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2597c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2607c478bd9Sstevel@tonic-gate gettext("bad alternate super block(%i) magic number\n"), i);
2617c478bd9Sstevel@tonic-gate exit(31+1);
2627c478bd9Sstevel@tonic-gate }
2636451fdbcSvsakar if ((altsblock.fs_magic == FS_MAGIC) &&
2646451fdbcSvsakar ((altsblock.fs_version !=
2656451fdbcSvsakar UFS_EFISTYLE4NONEFI_VERSION_2) &&
2666451fdbcSvsakar (altsblock.fs_version != UFS_VERSION_MIN))) {
2676451fdbcSvsakar (void) fprintf(stderr, gettext("labelit: "));
2686451fdbcSvsakar (void) fprintf(stderr,
2696451fdbcSvsakar gettext("bad alternate super block UFS format version: %d\n"),
2706451fdbcSvsakar altsblock.fs_version);
2716451fdbcSvsakar exit(31+1);
2726451fdbcSvsakar }
2737c478bd9Sstevel@tonic-gate if ((altsblock.fs_magic == MTB_UFS_MAGIC) &&
2747c478bd9Sstevel@tonic-gate ((altsblock.fs_version > MTB_UFS_VERSION_1) ||
2757c478bd9Sstevel@tonic-gate (altsblock.fs_version < MTB_UFS_VERSION_MIN))) {
2767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2777c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2787c478bd9Sstevel@tonic-gate gettext("bad alternate super block UFS format version: %d\n"),
2797c478bd9Sstevel@tonic-gate altsblock.fs_version);
2807c478bd9Sstevel@tonic-gate exit(31+1);
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate bcopy((char *)&(fs_rotbl(fsp)[blk]),
2837c478bd9Sstevel@tonic-gate (char *)&(fs_rotbl(altfsp)[blk]), 14);
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate if (llseek(f, offset, 0) < 0) {
2867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2877c478bd9Sstevel@tonic-gate perror("llseek");
2887c478bd9Sstevel@tonic-gate exit(31+1);
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate if (write(f, &altsblock, SBSIZE) != SBSIZE) {
2917c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("labelit: "));
2927c478bd9Sstevel@tonic-gate perror("write");
2937c478bd9Sstevel@tonic-gate exit(31+1);
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate p = (char *)&(fs_rotbl(fsp)[blk]);
2987c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("fsname: "));
2997c478bd9Sstevel@tonic-gate for (i = 0; (i < 6) && (*p); i++, p++) {
3007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%c", *p);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n");
3037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("volume: "));
3047c478bd9Sstevel@tonic-gate p++;
3057c478bd9Sstevel@tonic-gate for (i = 0; (i < 6); i++, p++) {
3067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%c", *p);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n");
3097c478bd9Sstevel@tonic-gate }
310