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

📄 open_by_label.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
字号:
/* *   Copyright (c) International Business Machines Corp., 2000-2007 * *   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 <sys/stat.h>#include <stdio.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <dirent.h>#include <errno.h>#include "jfs_types.h"#include "jfs_endian.h"#include "jfs_filsys.h"#include "jfs_superblock.h"#include "jfs_logmgr.h"#include "devices.h"#include "utilsubs.h"/* * LogOpenMode is kind of clunky, but it avoids passing a flag through several * layers of functions.  It should be either O_RDWR|O_EXCL or O_RDONLY. * Nothing should be writing to the journal device if any mounted file system * is using it. */int LogOpenMode = O_RDWR|O_EXCL;FILE * open_check_label(char *device, uuid_t uuid, int is_label, int is_log,		     int *in_use){	FILE *fp = NULL;	struct logsuper logsup;	struct superblock super;	if (in_use)		*in_use = 0;	if (LogOpenMode == O_RDONLY)		fp = fopen(device, "r");	else {		fp = fopen_excl(device, "r+");		if ((fp == NULL) && in_use) {			*in_use = 1;			fp = fopen(device, "r");		}	}	if (fp == NULL)		return fp;	if (is_log) {		ujfs_rw_diskblocks(fp, LOGSUPER_B << L2LOGPSIZE,				   sizeof (struct logsuper), &logsup, GET);		ujfs_swap_logsuper(&logsup);		if (logsup.magic == LOGMAGIC) {			if (is_label) {				if (!strncmp(uuid, logsup.label, 16))					return fp;			} else {				if (!uuid_compare(uuid, logsup.uuid))					return fp;			}		}	} else {		ujfs_rw_diskblocks(fp, SUPER1_OFF, sizeof (super), &super, GET);		ujfs_swap_superblock(&super);		if (!memcmp(super.s_magic, JFS_MAGIC, 4)) {			if (is_label) {				if (!strncmp(uuid, super.s_label, 16))					return fp;			} else {				if (!uuid_compare(uuid, super.s_uuid))					return fp;			}		}	}	fclose(fp);	return (NULL);}/*-------------------------------------------------------------------- * NAME: walk_dir * * FUNCTION: Helper for open_by_label to recursively search a directory *	     for block devices with the specified label or uuid * * PARAMETERS:	path - path of directory to search, returns found device *		uuid - label or uuid * 		is_label - 1 if label, 0 if uuid * 		is_log - 0 if filesystem, 1 if external log * * RETURNS: *    >= 0 file descriptor of matching volume *    < 0  matching volume not found */FILE * walk_dir(char *path, uuid_t uuid, int is_label, int is_log, int *in_use){	FILE *fp = NULL;	DIR *lv_dir;	struct dirent *lv_ent;	int path_len;	struct stat st;	lv_dir = opendir(path);	if (lv_dir) {		strcat(path, "/");		path_len = strlen(path);		while ((lv_ent = readdir(lv_dir))) {			path[path_len] = 0;			if (!strcmp(lv_ent->d_name, ".") ||			    !strcmp(lv_ent->d_name, "..") ||			    !strcmp(lv_ent->d_name, ".nodes"))				continue;			strcat(path, lv_ent->d_name);			if (stat(path, &st))				continue;			if (S_ISBLK(st.st_mode))				fp = open_check_label(path, uuid, is_label,						      is_log, in_use);			else if (S_ISDIR(st.st_mode))				fp = walk_dir(path, uuid, is_label, is_log,					      in_use);			else				continue;			if (fp) {				closedir(lv_dir);				return fp;			}		}		closedir(lv_dir);	}	return NULL;}/*-------------------------------------------------------------------- * NAME: open_by_label * * FUNCTION: Search /proc/partitions for volume having specified *	     label or uuid * * PARAMETERS:	uuid - label or uuid * 		is_label - 1 if label, 0 if uuid * 		is_log - 0 if filesystem, 1 if external log *		dev - if not null, returns copy of device path * * RETURNS: *    >= 0 file descriptor of matching volume *    < 0  matching volume not found * * NOTE: We may want to cache the uuids already found */FILE *open_by_label(uuid_t uuid, int is_label, int is_log, char *dev, int *in_use){	char device[100];	FILE *fp;	char line[100];	DIR *lv_dir;	char lv_dirname[100];	struct dirent *lv_ent;	int size;	FILE *part_fd;	char part_name[95];	DIR *vg_dir;	struct dirent *vg_ent;// #ifndef __DragonFly__	/*	 * Check for EVMS Release 1 volumes	 */	part_fd = fopen("/proc/evms/volumes", "r");	if (part_fd) {		/* evms/volumes should be complete.  If it exists, don't		 * search /proc/partitions or /proc/lvm		 */		while (fgets(line, sizeof (line), part_fd)) {			if (sscanf(line, " %*d %*d %*d %*s %*s %s", device)			    != 1)				continue;			fp = open_check_label(device, uuid, is_label, is_log,					      in_use);			if (fp != NULL) {				if (dev)					strcpy(dev, device);				fclose(part_fd);				return fp;			}		}		fclose(part_fd);		printf("Could not locate device by label or uuid!\n");		return (NULL);	}	/*	 * Check for evms release 2 volumes	 */	strcpy(device, "/dev/evms");	fp = walk_dir(device, uuid, is_label, is_log, in_use);	if (fp != NULL) {		if (dev)			strcpy(dev, device);		return fp;	}	/*	 * For RAID, check /proc/mdstat before /proc/partitions.	 * We don't want to find a device in /proc/partitions that is a	 * subset of a journal on a raid device	 */	part_fd = fopen("/proc/mdstat", "r");	if (part_fd) {		while (fgets(line, sizeof(line), part_fd)) {			char tmp[4];			/* reading tmp requires matching "active" */			if (sscanf(line, "%s : active %1s", part_name, tmp) != 2)				continue;			sprintf(device, "/dev/%s", part_name);			fp = open_check_label(device, uuid, is_label, is_log,					      in_use);			if (fp != NULL) {				if (dev)					strcpy(dev, device);				fclose(part_fd);				return fp;			}		}		fclose(part_fd);	}	/* Nothing yet.  Check /proc/partitions */	part_fd = fopen("/proc/partitions", "r");	if (part_fd) {		while (fgets(line, sizeof (line), part_fd)) {			if (sscanf(line, " %*d %*d %d %s", &size, part_name) != 2)				continue;			if (size == 1)	/* extended partition */				continue;			sprintf(device, "/dev/%s", part_name);			fp = open_check_label(device, uuid, is_label, is_log,					      in_use);			if (fp != NULL) {				if (dev)					strcpy(dev, device);				fclose(part_fd);				return fp;			}		}		fclose(part_fd);	} else		printf("Could not open /proc/partitions!\n");	/* Not found yet.  Check for lvm volumes */	vg_dir = opendir("/proc/lvm/VGs");	if (vg_dir) {		seekdir(vg_dir, 2);		while ((vg_ent = readdir(vg_dir))) {			sprintf(lv_dirname, "/proc/lvm/VGs/%s/LVs", vg_ent->d_name);			lv_dir = opendir(lv_dirname);			if (lv_dir == NULL) {				printf("can't open %s\n", lv_dirname);				continue;			}			seekdir(lv_dir, 2);			while ((lv_ent = readdir(lv_dir))) {				sprintf(device, "/dev/%s/%s", vg_ent->d_name, lv_ent->d_name);				fp = open_check_label(device, uuid, is_label,						      is_log, in_use);				if (fp != NULL) {					if (dev)						strcpy(dev, device);					closedir(lv_dir);					closedir(vg_dir);					return fp;				}			}			closedir(lv_dir);		}		closedir(vg_dir);	}	printf("Could not locate device by label or uuid!\n");/* #endif */	return (NULL);}

⌨️ 快捷键说明

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