⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tune.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
字号:
/* *   Copyright (c) International Business Machines Corp., 2000-2002 * *   This program is free software;  you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY;  without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See *   the GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program;  if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <config.h>#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <ctype.h>#include "jfs_types.h"#include "jfs_endian.h"#include "jfs_filsys.h"#include "jfs_superblock.h"#include "inode.h"#include "super.h"#include "jfs_version.h"#include "utilsubs.h"#define EXIT(fd, rc)  {fclose(fd); exit(rc);}static int J_flag, l_flag, L_flag, U_flag;char *new_label, *new_UUID;char *device;char logdev[255] = { '\0' };FILE *log_fd = NULL;int log_desc = -1;char *OpenMode = "r";extern int LogOpenMode;extern FILE * open_by_label(uuid_t, int, int, char *, int *);extern void display_logsuper(struct logsuper *);extern void display_super(struct superblock *);void tune_usage(void){	printf("\nUsage:  jfs_tune [-J options] [-l] [-L vol_label] [-U uuid] [-V] device\n"	       "\nEmergency help:\n"	       " -J options    Set external journal options.\n"	       " -l            Display superblock\n"	       " -L vol_label  Set volume label.\n"	       " -U uuid       Set UUID.\n"	       " -V            Print version information only.\n");	exit(-1);}/*-------------------------------------------------------------------- * NAME: parse_journal_opts * * FUNCTION: parse journal (-J) options *           set log file descriptor (global log_fd) *           set log device name (global logdev) * * PARAMETERS: *      opts - options string */void parse_journal_opts(const char *opts){	int journal_usage = 0;	uuid_t log_uuid;	int in_use;	LogOpenMode = O_RDONLY;	if (strncmp(opts, "device=", 7) == 0) {		if (strncmp(opts + 7, "UUID=", 5) == 0) {			if (uuid_parse((char *) opts + 7 + 5, log_uuid)) {				fputs("\nError: UUID entered in improper format.\n",				      stderr);				exit(-1);			} else {				log_fd = open_by_label(log_uuid, 0, 1, logdev,						       &in_use);			}		} else if (strncmp(opts + 7, "LABEL=", 6) == 0) {			log_fd = open_by_label((char *) opts + 7 + 6, 1, 1,					       logdev, &in_use);		} else {			strcpy(logdev, ((char *) opts + 7));			if (logdev)				log_fd = fopen(logdev, "r");			else				journal_usage++;		}	} else		journal_usage++;	if (journal_usage) {		fprintf(stderr, "\nInvalid journal option(s) specified.\n\n"				"Valid options for -J are:\n"				"\tdevice=<journal device>\n"				"\tdevice=UUID=<UUID of journal device>\n"				"\tdevice=LABEL=<label of journal device>\n\n");		exit(1);	}	return;}/*-------------------------------------------------------------------- * NAME: parse_tune_options * * FUNCTION: parse tune options * * PARAMETERS: *      argc - number of passed arguments *      argv - string of arguments * * RETURNS: *      success: 0 *      failure: any other value */static void parse_tune_options(int argc, char *argv[]){	int c;	while ((c = getopt(argc, argv, "J:lL:U:V")) != EOF) {		switch (c) {		case 'J':			/* attach external journal device */			parse_journal_opts(optarg);			J_flag = 1;			OpenMode = "r+";			break;		case 'l':			/* display superblock */			l_flag = 1;			break;		case 'L':			/* set volume label */			new_label = optarg;			L_flag = 1;			OpenMode = "r+";			break;		case 'U':			/* set UUID */			new_UUID = optarg;			U_flag = 1;			OpenMode = "r+";			break;		case 'V':			/* print version and exit */			exit(0);			break;		default:			tune_usage();			break;		}	}	if (optind != argc - 1) {		printf("\nError: Device not specified or command format error.\n");		tune_usage();	}	if (!J_flag && !l_flag && !L_flag && !U_flag) {		printf("\nError: No options selected.\n");		tune_usage();	}	device = argv[optind];	return;}/*-------------------------------------------------------------------- * NAME: main * * FUNCTION: adjust JFS tunable parameters * * PARAMETERS: *      argc - number of passed arguments *      argv - string of arguments * * RETURNS: *      success: 0 *      failure: any other value */int main(int argc, char *argv[]){	FILE *fp = NULL;	int rc = 0;	int superblock_type;	bool mounted = false;	struct superblock sb;	struct logsuper logsup;#define FS_SUPER_SECONDARY  0#define FS_SUPER_PRIMARY    1#define LOG_SUPER           2	printf("jfs_tune version %s, %s\n", VERSION, JFSUTILS_DATE);	parse_tune_options(argc, argv);	/*	 * Check if device is mounted.  -l is the only parameter	 * supported on a mounted device, so if any others are	 * selected, let the user know.  If the device is mounted	 * and -l was not specified, get out.	 */	rc = Is_Device_Mounted(device);	if (rc) {		mounted = true;		if (J_flag || L_flag || U_flag) {			fprintf(stderr, "\n%s is mounted.\n"				"While mounted, the only supported jfs_tune parameter is -l.\n",				device);			if (!l_flag) {				exit(-1);			}		}	}	/* Open device */	if (J_flag)		fp = fopen_excl(device, "r+");	else		fp = fopen(device, OpenMode);	if (fp == NULL) {		fprintf(stderr, "Error: Cannot open device %s.\n", device);		exit(-1);	}	/* Get and validate primary JFS superblock */	if ((rc = ujfs_get_superblk(fp, &sb, 1)) == 0) {		if ((rc = ujfs_validate_super(&sb)) == 0) {			superblock_type = FS_SUPER_PRIMARY;		}	}	/* If failure retrieving primary superblock, get/validate secondary superblock */	if (rc) {		if ((rc = ujfs_get_superblk(fp, &sb, 0)) == 0) {			if ((rc = ujfs_validate_super(&sb)) == 0) {				superblock_type = FS_SUPER_SECONDARY;			}		}	}	/* If no valid FS superblock, see if we have a log superblock */	if (rc) {		if ((rc = ujfs_get_logsuper(fp, &logsup)) == 0) {			if ((rc = ujfs_validate_logsuper(&logsup)) == 0) {				superblock_type = LOG_SUPER;				/*				 * We know this is an external journal device.				 * Now check to see if it is attached to a				 * mounted file system.  If so, the only				 * valid option is -l.				 */				if (logsup.state == LOGMOUNT) {					mounted = true;					if (J_flag || L_flag || U_flag) {						fprintf(stderr,							"\n%s contains an external journal for a mounted filesystem.\n"							"While mounted, the only supported jfs_tune parameter is -l.\n",							device);						if (!l_flag) {							EXIT(fp, -1);						}					}				}			}		}	}	/* If we couldn't find/read a valid JFS FS or log superblock, warn user and exit */	if (rc) {		printf("\nCould not read valid JFS FS or log superblock on device %s.\n",		       device);		EXIT(fp, -1);	}	/*	 * Account for bug in mkfs.jfs 1.0.18 and 1.0.19	 * that didn't properly set the file system version	 * number to 2 when using an external journal.	 */	if (!mounted && (superblock_type < LOG_SUPER) &&	    (sb.s_version < JFS_VERSION) && !(sb.s_flag & JFS_INLINELOG)) {		sb.s_version = JFS_VERSION;		rc = ujfs_put_superblk(fp, &sb, superblock_type);		if (rc) {			printf("\nCould not update JFS version number properly on %s.\n",			       device);			EXIT(fp, rc);		}	}	/*	 * set volume label on unmounted device	 */	if (L_flag && !mounted) {		if (superblock_type < LOG_SUPER) {			/* change label in JFS file system superblock */			/*			 * The superblock in JFS releases before 1.0.18 stores			 * the label in s_fpack[11].  The superblock in JFS			 * releases 1.0.18 and greater has s_fpack, but uses			 * the new field s_label[16] to store the label.			 * s_label is in an area of the superblock that was			 * allocated but unused in pre 1.0.18, so if per chance			 * the user is using an old JFS file system, setting			 * s_label will not be a problem.			 */			memset(sb.s_fpack, 0, sizeof (sb.s_fpack));			strncpy(sb.s_fpack, new_label, sizeof (sb.s_fpack));			if (strlen(new_label) > sizeof (sb.s_label))				fprintf(stderr, "Warning: label too long, truncating.\n");			memset(sb.s_label, 0, sizeof (sb.s_label));			strncpy(sb.s_label, new_label, sizeof (sb.s_label));			rc = ujfs_put_superblk(fp, &sb, superblock_type);		} else {			/* change label in JFS log superblock */			if (strlen(new_label) > sizeof (logsup.label))				fprintf(stderr, "Warning: label too long, truncating.\n");			memset(logsup.label, 0, sizeof (logsup.label));			strncpy(logsup.label, new_label, sizeof (logsup.label));			rc = ujfs_put_logsuper(fp, &logsup);		}		if (rc) {			printf("\nError writing superblock to disk.  Label unchanged.\n");			EXIT(fp, rc);		} else {			printf("Volume label updated successfully.\n");		}	}	/*	 * set UUID on umounted device	 */	if (U_flag && !mounted) {		uuid_t *uu;		uu = ((superblock_type < LOG_SUPER) ? &sb.s_uuid : &logsup.uuid);		if ((strcasecmp(new_UUID, "null") == 0) ||		    (strcasecmp(new_UUID, "clear") == 0)) {			uuid_clear(*uu);		} else if (strcasecmp(new_UUID, "time") == 0) {			uuid_generate_time(*uu);		} else if (strcasecmp(new_UUID, "random") == 0) {			uuid_generate(*uu);		} else if (uuid_parse(new_UUID, *uu)) {			fprintf(stderr, "Invalid UUID format.\n");			EXIT(fp, -1);		}		if (superblock_type < LOG_SUPER) {			/* mount(8) won't recognize uuid if jfs_version == 1 */			if (sb.s_version == 1) {				sb.s_version = 2;				/* Make sure s_label is set.  If it's valid,				 * the first 11 characters will match s_fpack				 */				if (strncmp(sb.s_fpack, sb.s_label, 11)) {					strncpy(sb.s_label, sb.s_fpack, 11);					sb.s_label[11] = 0;				}			}			rc = ujfs_put_superblk(fp, &sb, superblock_type);		} else {			rc = ujfs_put_logsuper(fp, &logsup);		}		if (rc) {			printf("\nError writing superblock to disk.  UUID unchanged.\n");			EXIT(fp, rc);		} else {			printf("UUID updated successfully.\n");		}	}	/*	 * attach external journal to JFS file system	 */	if (J_flag && !mounted) {		/*		 * NOTE: If we ever allow attaching more than one file system to a		 * single log file, we'll have to change the conditions of the above		 * 'if' to account for a log file that is in use by one file system		 * (state LOGMOUNT), but is being attached to by another file system.		 */		struct stat st;		/* make sure device to be attached to is a JFS file system */		if (superblock_type >= LOG_SUPER) {			printf("\nError: %s does not contain a JFS file system.\n",device);			EXIT(fp, -1);		}		/* log_fd was set in parse_journal_opts */		if (log_fd == NULL) {			printf("\nError: Could not find/open specified external journal device.\n");			EXIT(fp, -1);		}		/* get valid log superblock */		if ((rc = ujfs_get_logsuper(log_fd, &logsup)) == 0) {			if ((rc = ujfs_validate_logsuper(&logsup)) == 0) {				if (fstat(fileno(log_fd), &st)) {					rc = -1;				} else {					/* update FS superblock */					sb.s_logdev = st.st_rdev;					uuid_copy(sb.s_loguuid, logsup.uuid);					sb.s_version = JFS_VERSION;					sb.s_flag &= (~JFS_INLINELOG);					memset(&sb.s_logpxd, 0, sizeof (pxd_t));					rc = ujfs_put_superblk(fp, &sb, superblock_type);				}			}		}		/* If we could't find/read a valid JFS log superblock, let user know */		if (rc) {			printf("\nError attaching JFS external journal to JFS FS.\n");		} else {			printf("Attached JFS external journal to JFS FS successfully.\n");		}		fclose(log_fd);	}	/*	 * display superblock	 */	if (l_flag) {		if (superblock_type < LOG_SUPER) {			display_super(&sb);		} else {			display_logsuper(&logsup);		}	}	fclose(fp);	return rc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -