xref: /titanic_51/usr/src/cmd/fs.d/ufs/labelit/labelit.c (revision d1a180b0452ce86577a43be3245d2eacdeec1a34)
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