Ejemplo n.º 1
0
static void
uuidcache_init(void) {
    char line[100];
    char *s;
    int ma, mi, sz;
    static char ptname[100];
    FILE *procpt;
    char uuid[16], *label;
    char device[110];
    int firstPass;
    int handleOnFirst;

    if (uuidCache)
        return;

    procpt = fopen(PROC_PARTITIONS, "r");
    if (!procpt)
        return;

    for (firstPass = 1; firstPass >= 0; firstPass--) {
        fseek(procpt, 0, SEEK_SET);

        while (fgets(line, sizeof(line), procpt)) {
            if (sscanf (line, " %d %d %d %[^\n ]",
                        &ma, &mi, &sz, ptname) != 4)
                continue;

            /* skip extended partitions (heuristic: size 1) */
            if (sz == 1)
                continue;

            /* look only at md devices on first pass */
            handleOnFirst = !strncmp(ptname, "md", 2);
            if (firstPass != handleOnFirst)
                continue;

            /* skip entire disk (minor 0, 64, ... on ide;
               0, 16, ... on sd) */
            /* heuristic: partition name ends in a digit */

            for(s = ptname; *s; s++);
            if (isdigit(s[-1])) {
                /*
                 * Note: this is a heuristic only - there is no reason
                 * why these devices should live in /dev.
                 * Perhaps this directory should be specifiable by option.
                 * One might for example have /devlabel with links to /dev
                 * for the devices that may be accessed in this way.
                 * (This is useful, if the cdrom on /dev/hdc must not
                 * be accessed.)
                 */
                sprintf(device, "%s/%s", DEVLABELDIR, ptname);
                if (!get_label_uuid(device, &label, uuid))
                    uuidcache_addentry(strdup(device), label, uuid);
            }
        }
    }

    fclose(procpt);
}
Ejemplo n.º 2
0
static void
uuidcache_check_device(const char *device_name, int ma, int mi, int iso_only)
{
	char *device, *last_slash;
	char *uuid, *label;
	char *ptr;
	int must_remove = 0;
	int added = 0;

	last_slash = NULL;
	device = xasprintf("/dev/%s", device_name);
	if (access(device, F_OK) != 0) {
		/* device does not exist, temporarily create */
		int slash_cnt = 0;

		if ((ma | mi) < 0)
			goto ret; /* we don't know major:minor! */

		ptr = device;
		while (*ptr)
			if (*ptr++ == '/')
				slash_cnt++;
		if (slash_cnt > 2) {
// BUG: handles only slash_cnt == 3 case
			last_slash = strrchr(device, '/');
			*last_slash = '\0';
			if (mkdir(device, 0644)) {
				bb_perror_msg("can't create directory %s", device);
				*last_slash = '/';
				last_slash = NULL; /* prevents rmdir */
			} else {
				*last_slash = '/';
			}
		}
		mknod(device, S_IFBLK | 0600, makedev(ma, mi));
		must_remove = 1;
	}

	uuid = NULL;
	label = NULL;
	if (get_label_uuid(device, &label, &uuid, iso_only) == 0) {
		uuidcache_addentry(device, /*ma, mi,*/ label, uuid);
		/* "device" is owned by cache now, don't free */
		added = 1;
	}

	if (must_remove)
		unlink(device);
	if (last_slash) {
		*last_slash = '\0';
		rmdir(device);
	}
 ret:
	if (!added)
		free(device);
}
Ejemplo n.º 3
0
static void init_lvm(void)
{
	DIR		*vg_dir, *lv_list;
	char		*vdirname, *lvm_device;
	char		uuid[16], *label, *vname, *lname;
	struct dirent 	*vg_iter, *lv_iter;
	
	if ((vg_dir = opendir(VG_DIR)) == NULL)
		return;

	while ((vg_iter = readdir(vg_dir)) != 0) {
		vname = vg_iter->d_name;
		if (!strcmp(vname, ".") || !strcmp(vname, ".."))
			continue;
		vdirname = malloc(strlen(VG_DIR)+strlen(vname)+8);
		if (!vdirname) {
			closedir(vg_dir);
			return;
		}
		sprintf(vdirname, "%s/%s/LVs", VG_DIR, vname);

		lv_list = opendir(vdirname);
		free(vdirname);
		if (lv_list == NULL)
			return;

		while ((lv_iter = readdir(lv_list)) != 0) {
			lname = lv_iter->d_name;
			if (!strcmp(lname, ".") || !strcmp(lname, ".."))
				continue;

			lvm_device = malloc(strlen(DEVLABELDIR) +
					    strlen(vname)+
					    strlen(lname)+8);
			if (!lvm_device) {
				closedir(lv_list);
				closedir(vg_dir);
				return;
			}
			sprintf(lvm_device, "%s/%s/%s", DEVLABELDIR,
				vname, lname);
			if (!get_label_uuid(lvm_device, &label, uuid)) {
				uuidcache_addentry(string_copy(lvm_device),
						   label, uuid);
			} else
				free(lvm_device);
		}
		closedir(lv_list);
	}
	closedir( vg_dir );
}
Ejemplo n.º 4
0
static void
read_evms(void)
{
	char line[100];
	int ma, mi, sz;
	FILE *procpt;
	char uuid[16], *label, *devname;
	char device[110];
	dev_t	dev;
	struct stat statbuf;

	procpt = fopen(PROC_EVMS_VOLUMES, "r");
	if (!procpt)
		return;
	while (fgets(line, sizeof(line), procpt)) {
		if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
			    &ma, &mi, &sz, device) != 4)
			continue;

		/*
		 * We first look for the device in the named location,
		 * but if we don't find it, or if the stat information
		 * doesn't check out, we use ext2fs_find_block_device
		 * to find it.
		 */
		dev = makedev(ma, mi);
		if ((stat(device, &statbuf) < 0) || (statbuf.st_rdev != dev)) {
			devname = ext2fs_find_block_device(dev);
		} else
			devname = string_copy(device);
		if (!devname)
			continue;
#ifdef DEBUG
		printf("Checking partition %s (%d, %d)\n",
		       devname, ma, mi);
#endif
		if (!get_label_uuid(devname, &label, uuid))
			uuidcache_addentry(devname, label, uuid);
		else
			free(devname);
	}
	fclose(procpt);
}
Ejemplo n.º 5
0
static int
uuidcache_init_evms(void) {
	FILE *procvol;
	char *label;
	char uuid[16];
	char volname[EVMS_VOLUME_NAME_SIZE+1];
	char line[EVMS_VOLUME_NAME_SIZE+80];

	procvol = fopen(PROC_EVMS_VOLUMES, "r");
	if (!procvol)
		return 0;

	while (fgets(line, sizeof(line), procvol)) {
		if (sscanf(line, "%*d %*d %*d %*s %*s %[^\n]", volname) == 1) {
			if (!get_label_uuid(volname, &label, uuid))
				uuidcache_addentry(xstrdup(volname), label, uuid);
		}
	}
	
	fclose(procvol);
	
	return 1;
}
Ejemplo n.º 6
0
/* LVM support - Kirby Bohling */
static void
uuidcache_init_lvm(void) {
	char buffer[PATH_MAX];
	char lvm_device[PATH_MAX];
	DIR *vg_dir, *lv_list;
	struct dirent *vg_iter, *lv_iter;
	char uuid[16], *label;

	vg_dir = opendir(VG_DIR);
	if (vg_dir == NULL)	/* to be expected */
		return;

	seekdir(vg_dir, 2);
	while ((vg_iter = readdir(vg_dir)) != 0) {
		sprintf(buffer, "%s/%s/LVs", VG_DIR, vg_iter->d_name);
		lv_list = opendir(buffer);
		if (lv_list == NULL) {
			perror("uuidcache_init_lvm");
			continue;
		}
		seekdir(lv_list, 2);
		while ((lv_iter = readdir(lv_list)) != 0) {
			/* Now we have the file.. could open it and read out
			 * where the device is, read the first line, second
			 * field... Instead we guess.
			 */
			sprintf(lvm_device, "%s/%s/%s", DEVLABELDIR,
				vg_iter->d_name, lv_iter->d_name);
			if (!get_label_uuid(lvm_device, &label, uuid))
				uuidcache_addentry(xstrdup(lvm_device),
						   label, uuid);
		}
		closedir(lv_list);
	}
	closedir(vg_dir);
}
Ejemplo n.º 7
0
static void
uuidcache_init(void) {
	char line[100];
	char *s;
	int ma, mi, sz;
	static char ptname[100];
	FILE *procpt;
	char uuid[16], *label;
	char device[110];
	int firstPass;
	int handleOnFirst;
#if 0
	char iobuf[32*1024];	/* For setvbuf */
#endif

	if (uuidCache)
		return;

	if (uuidcache_init_evms())
		return;

	procpt = fopen(PROC_PARTITIONS, "r");
	if (!procpt) {
		static int warn = 0;
		if (!warn++)
		    error (_("%s: could not open %s, so UUID and LABEL "
			     "conversion cannot be done.\n"),
			   progname, PROC_PARTITIONS);
		return;
	}
#if 0
/* Ugly kludge - the contents of /proc/partitions change in time,
   and this causes failures when the file is not read in one go.
   In particular, one cannot use stdio on /proc/partitions.
   Doing this ourselves is not easy either, since stat returns 0
   so the size is unknown. We might try increasing buffer sizes
   until a single read gets all. For now only pick a largish buffer size. */
/* All these troubles are mainly caused by people who patch the kernel
   to keep statistics in /proc/partitions. Of course, statistics belong
   in some /proc/diskstats, not in some /proc file that happened to
   exist already. */

	setvbuf(procpt, iobuf, _IOFBF, sizeof(iobuf));
#endif

	for (firstPass = 1; firstPass >= 0; firstPass--) {
	    fseek(procpt, 0, SEEK_SET);

	    while (fgets(line, sizeof(line), procpt)) {
		if (!index(line, '\n'))
			break;

		if (sscanf (line, " %d %d %d %[^\n ]",
			    &ma, &mi, &sz, ptname) != 4)
			continue;

		/* skip extended partitions (heuristic: size 1) */
		if (sz == 1)
			continue;

		/* look only at md devices on first pass */
		handleOnFirst = !strncmp(ptname, "md", 2);
		if (firstPass != handleOnFirst)
			continue;

		/* skip entire disk (minor 0, 64, ... on ide;
		   0, 16, ... on sd) */
		/* heuristic: partition name ends in a digit */
		/* devfs has .../disc and .../part1 etc. */

		for (s = ptname; *s; s++);
		if (isdigit(s[-1]) || is_xvm(ptname)) {
			
		/*
		 * Note: this is a heuristic only - there is no reason
		 * why these devices should live in /dev.
		 * Perhaps this directory should be specifiable by option.
		 * One might for example have /devlabel with links to /dev
		 * for the devices that may be accessed in this way.
		 * (This is useful, if the cdrom on /dev/hdc must not
		 * be accessed.)
		 */
			sprintf(device, "%s/%s", DEVLABELDIR, ptname);
			if (!get_label_uuid(device, &label, uuid))
				uuidcache_addentry(xstrdup(device), label, uuid);
		}
	    }
	}

	fclose(procpt);

	uuidcache_init_lvm();
}
Ejemplo n.º 8
0
static void
read_partitions(void)
{
	char line[100];
	char *s;
	int ma, mi, sz;
	static char ptname[100];
	FILE *procpt;
	char uuid[16], *label, *devname;
	char device[110];
	dev_t	dev;
	struct stat statbuf;
	int firstPass;
	int handleOnFirst;
	char *iobuf;

	procpt = fopen(PROC_PARTITIONS, "r");
	if (!procpt)
		return;

	iobuf = (char *)malloc(CBBUF);
	if (iobuf)
		setvbuf(procpt, iobuf, _IOFBF, CBBUF);

	for (firstPass = 1; firstPass >= 0; firstPass--) {
	    fseek(procpt, 0, SEEK_SET);

	    while (fgets(line, sizeof(line), procpt)) {
		if (sscanf (line, " %d %d %d %[^\n ]",
			    &ma, &mi, &sz, ptname) != 4)
			continue;

		/* skip extended partitions (heuristic: size 1) */
		if (sz == 1)
			continue;

		/* look only at md devices on first pass */
		handleOnFirst = !strncmp(ptname, "md", 2);
		if (firstPass != handleOnFirst)
			continue;

		/* skip entire disk (minor 0, 64, ... on ide;
		   0, 16, ... on sd) */
		/* heuristic: partition name ends in a digit */
		/* OR partition name starts with 'lvm' */

		for(s = ptname; *s; s++);
		if (isdigit(s[-1]) || !strncmp(ptname, "lvm", 3)) {
			/*
			 * We first look in /dev for the device, but
			 * if we don't find it, or if the stat
			 * information doesn't check out, we use
			 * ext2fs_find_block_device to find it.
			 */
			sprintf(device, "%s/%s", DEVLABELDIR, ptname);
			dev = makedev(ma, mi);
			if ((stat(device, &statbuf) < 0) ||
			    (statbuf.st_rdev != dev)) {
				devname = ext2fs_find_block_device(dev);
			} else
				devname = string_copy(device);
			if (!devname)
				continue;
#ifdef DEBUG
			printf("Checking partition %s (%d, %d)\n",
			       devname, ma, mi);
#endif
			if (!get_label_uuid(devname, &label, uuid))
				uuidcache_addentry(devname, label, uuid);
			else
				free(devname);
		}
	    }
	}

	fclose(procpt);
	if (iobuf)
		free(iobuf);
}