volume identification: abolish /proc/partitions and /proc/cdroms
scanning. It does not catch volume managers and such. Adding even more cruft is bad, so I decided to simply scan /dev/* for any block devices. See how much better it finds devices now: # ./busybox_old blkid /dev/sda1: LABEL="/boot" UUID="7931e231-dcb4-4b6d-9301-f7354ae24061" /dev/dm-0: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a" /dev/dm-1: UUID="edc2a920-ef83-437e-ba64-d3b6dc851267" /dev/sdb1: UUID="6F84-ED0F" # ./busybox blkid /dev/sdb1: UUID="6F84-ED0F" /dev/root: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a" /dev/dm-1: UUID="edc2a920-ef83-437e-ba64-d3b6dc851267" /dev/dm-0: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a" /dev/sda1: LABEL="/boot" UUID="7931e231-dcb4-4b6d-9301-f7354ae24061" /dev/mapper/VolGroup00-LogVol01: UUID="edc2a920-ef83-437e-ba64-d3b6dc851267" /dev/mapper/VolGroup00-LogVol00: LABEL="Fedora-9-Live-x8" UUID="bb491e1e-1145-4f5b-b0ab-cbd2baf4f15a" function old new delta static.drive_name_string 12 - -12 append_mount_options 205 190 -15 volume_id_open_node 37 18 -19 uuidcache_check_device 485 257 -228 uuidcache_init 637 36 -601 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/4 up/down: 0/-875) Total: -875 bytes text data bss dec hex filename 792218 592 6648 799458 c32e2 busybox_old 791260 592 6648 798500 c2f24 busybox_unstripped
This commit is contained in:
parent
bff06fe02a
commit
582dff0514
@ -1189,7 +1189,7 @@ static char **get_recursive_dirlist(char *path)
|
|||||||
recursive_action(path, ACTION_RECURSE|ACTION_FOLLOWLINKS,
|
recursive_action(path, ACTION_RECURSE|ACTION_FOLLOWLINKS,
|
||||||
add_to_dirlist, /* file_action */
|
add_to_dirlist, /* file_action */
|
||||||
NULL, /* dir_action */
|
NULL, /* dir_action */
|
||||||
(void*)(strlen(path) + 1),
|
(void*)(ptrdiff_t)(strlen(path) + 1),
|
||||||
0);
|
0);
|
||||||
} else {
|
} else {
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
|
@ -71,7 +71,7 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
|
|||||||
}
|
}
|
||||||
/* Since the directory exists, don't attempt to change
|
/* Since the directory exists, don't attempt to change
|
||||||
* permissions if it was the full target. Note that
|
* permissions if it was the full target. Note that
|
||||||
* this is not an error conditon. */
|
* this is not an error condition. */
|
||||||
if (!c) {
|
if (!c) {
|
||||||
umask(mask);
|
umask(mask);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -22,38 +22,23 @@ static struct uuidCache_s {
|
|||||||
|
|
||||||
/* Returns !0 on error.
|
/* Returns !0 on error.
|
||||||
* Otherwise, returns malloc'ed strings for label and uuid
|
* Otherwise, returns malloc'ed strings for label and uuid
|
||||||
* (and they can't be NULL, although they can be "") */
|
* (and they can't be NULL, although they can be "").
|
||||||
#if !ENABLE_FEATURE_VOLUMEID_ISO9660
|
* NB: closes fd. */
|
||||||
#define get_label_uuid(device, label, uuid, iso_only) \
|
|
||||||
get_label_uuid(device, label, uuid)
|
|
||||||
#endif
|
|
||||||
static int
|
static int
|
||||||
get_label_uuid(const char *device, char **label, char **uuid, int iso_only)
|
get_label_uuid(int fd, char **label, char **uuid)
|
||||||
{
|
{
|
||||||
int rv = 1;
|
int rv = 1;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
struct volume_id *vid;
|
struct volume_id *vid;
|
||||||
|
|
||||||
vid = volume_id_open_node(device);
|
/* fd is owned by vid now */
|
||||||
if (!vid)
|
vid = volume_id_open_node(fd);
|
||||||
return rv;
|
|
||||||
|
|
||||||
if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
|
if (ioctl(/*vid->*/fd, BLKGETSIZE64, &size) != 0)
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_VOLUMEID_ISO9660
|
if (volume_id_probe_all(vid, 0, size) != 0)
|
||||||
if ((iso_only ?
|
|
||||||
volume_id_probe_iso9660(vid, 0) :
|
|
||||||
volume_id_probe_all(vid, 0, size)
|
|
||||||
) != 0
|
|
||||||
) {
|
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (volume_id_probe_all(vid, 0, size) != 0) {
|
|
||||||
goto ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (vid->label[0] != '\0' || vid->uuid[0] != '\0') {
|
if (vid->label[0] != '\0' || vid->uuid[0] != '\0') {
|
||||||
*label = xstrndup(vid->label, sizeof(vid->label));
|
*label = xstrndup(vid->label, sizeof(vid->label));
|
||||||
@ -62,7 +47,7 @@ get_label_uuid(const char *device, char **label, char **uuid, int iso_only)
|
|||||||
rv = 0;
|
rv = 0;
|
||||||
}
|
}
|
||||||
ret:
|
ret:
|
||||||
free_volume_id(vid);
|
free_volume_id(vid); /* also closes fd */
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,204 +76,29 @@ uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uu
|
|||||||
/* If get_label_uuid() on device_name returns success,
|
/* If get_label_uuid() on device_name returns success,
|
||||||
* add a cache entry for this device.
|
* add a cache entry for this device.
|
||||||
* If device node does not exist, it will be temporarily created. */
|
* If device node does not exist, it will be temporarily created. */
|
||||||
#if !ENABLE_FEATURE_VOLUMEID_ISO9660
|
static int FAST_FUNC
|
||||||
#define uuidcache_check_device(device_name, ma, mi, iso_only) \
|
uuidcache_check_device(const char *device,
|
||||||
uuidcache_check_device(device_name, ma, mi)
|
struct stat *statbuf,
|
||||||
#endif
|
void *userData UNUSED_PARAM,
|
||||||
static void
|
int depth UNUSED_PARAM)
|
||||||
uuidcache_check_device(const char *device_name, int ma, int mi, int iso_only)
|
|
||||||
{
|
{
|
||||||
char *device, *last_slash;
|
char *uuid = uuid; /* for compiler */
|
||||||
char *uuid, *label;
|
char *label = label;
|
||||||
char *ptr;
|
int fd;
|
||||||
int must_remove = 0;
|
|
||||||
int added = 0;
|
|
||||||
|
|
||||||
last_slash = NULL;
|
if (!S_ISBLK(statbuf->st_mode))
|
||||||
device = xasprintf("/dev/%s", device_name);
|
return TRUE;
|
||||||
if (access(device, F_OK) != 0) {
|
|
||||||
/* device does not exist, temporarily create */
|
|
||||||
int slash_cnt = 0;
|
|
||||||
|
|
||||||
if ((ma | mi) < 0)
|
fd = open(device, O_RDONLY);
|
||||||
goto ret; /* we don't know major:minor! */
|
if (fd < 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
ptr = device;
|
/* get_label_uuid() closes fd in all cases (success & failure) */
|
||||||
while (*ptr)
|
if (get_label_uuid(fd, &label, &uuid) == 0) {
|
||||||
if (*ptr++ == '/')
|
/* uuidcache_addentry() takes ownership of all three params */
|
||||||
slash_cnt++;
|
uuidcache_addentry(xstrdup(device), /*ma, mi,*/ label, uuid);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run uuidcache_check_device() for every device mentioned
|
|
||||||
* in /proc/partitions */
|
|
||||||
static void
|
|
||||||
uuidcache_init_partitions(void)
|
|
||||||
{
|
|
||||||
char line[100];
|
|
||||||
int ma, mi;
|
|
||||||
unsigned long long sz;
|
|
||||||
FILE *procpt;
|
|
||||||
int firstPass;
|
|
||||||
int handleOnFirst;
|
|
||||||
char *chptr;
|
|
||||||
|
|
||||||
procpt = xfopen_for_read("/proc/partitions");
|
|
||||||
/*
|
|
||||||
# cat /proc/partitions
|
|
||||||
major minor #blocks name
|
|
||||||
|
|
||||||
8 0 293036184 sda
|
|
||||||
8 1 6835626 sda1
|
|
||||||
8 2 1 sda2
|
|
||||||
8 5 979933 sda5
|
|
||||||
8 6 15623181 sda6
|
|
||||||
8 7 97659103 sda7
|
|
||||||
8 8 171935631 sda8
|
|
||||||
*/
|
|
||||||
for (firstPass = 1; firstPass >= 0; firstPass--) {
|
|
||||||
fseek(procpt, 0, SEEK_SET);
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), procpt)) {
|
|
||||||
/* The original version of this code used sscanf, but
|
|
||||||
diet's sscanf is quite limited */
|
|
||||||
chptr = line;
|
|
||||||
if (*chptr != ' ') continue;
|
|
||||||
chptr = skip_whitespace(chptr);
|
|
||||||
|
|
||||||
ma = bb_strtou(chptr, &chptr, 0);
|
|
||||||
if (ma < 0) continue;
|
|
||||||
chptr = skip_whitespace(chptr);
|
|
||||||
|
|
||||||
mi = bb_strtou(chptr, &chptr, 0);
|
|
||||||
if (mi < 0) continue;
|
|
||||||
chptr = skip_whitespace(chptr);
|
|
||||||
|
|
||||||
sz = bb_strtoull(chptr, &chptr, 0);
|
|
||||||
if ((long long)sz == -1LL) continue;
|
|
||||||
chptr = skip_whitespace(chptr);
|
|
||||||
|
|
||||||
/* skip extended partitions (heuristic: size 1) */
|
|
||||||
if (sz == 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
*strchrnul(chptr, '\n') = '\0';
|
|
||||||
/* now chptr => device name */
|
|
||||||
dbg("/proc/partitions: maj:%d min:%d sz:%llu name:'%s'",
|
|
||||||
ma, mi, sz, chptr);
|
|
||||||
if (!chptr[0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* look only at md devices on first pass */
|
|
||||||
handleOnFirst = (chptr[0] == 'm' && chptr[1] == 'd');
|
|
||||||
if (firstPass != handleOnFirst)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* heuristic: partition name ends in a digit */
|
|
||||||
if (isdigit(chptr[strlen(chptr) - 1])) {
|
|
||||||
uuidcache_check_device(chptr, ma, mi, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(procpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dev_get_major_minor(char *device_name, int *major, int *minor)
|
|
||||||
{
|
|
||||||
char dev[16];
|
|
||||||
char *dev_path;
|
|
||||||
char *colon;
|
|
||||||
int sz;
|
|
||||||
|
|
||||||
dev_path = xasprintf("/sys/block/%s/dev", device_name);
|
|
||||||
sz = open_read_close(dev_path, dev, sizeof(dev) - 1);
|
|
||||||
if (sz < 0)
|
|
||||||
goto ret;
|
|
||||||
dev[sz] = '\0';
|
|
||||||
|
|
||||||
colon = strchr(dev, ':');
|
|
||||||
if (!colon)
|
|
||||||
goto ret;
|
|
||||||
*major = bb_strtou(dev, NULL, 10);
|
|
||||||
*minor = bb_strtou(colon + 1, NULL, 10);
|
|
||||||
|
|
||||||
ret:
|
|
||||||
free(dev_path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
uuidcache_init_cdroms(void)
|
|
||||||
{
|
|
||||||
#define PROC_CDROMS "/proc/sys/dev/cdrom/info"
|
|
||||||
char line[100];
|
|
||||||
int ma, mi;
|
|
||||||
FILE *proccd;
|
|
||||||
|
|
||||||
proccd = fopen_for_read(PROC_CDROMS);
|
|
||||||
if (!proccd) {
|
|
||||||
// static smallint warn = 0;
|
|
||||||
// if (!warn) {
|
|
||||||
// warn = 1;
|
|
||||||
// bb_error_msg("can't open %s, UUID and LABEL "
|
|
||||||
// "conversion cannot be done for CD-Roms",
|
|
||||||
// PROC_CDROMS);
|
|
||||||
// }
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), proccd)) {
|
|
||||||
static const char drive_name_string[] ALIGN1 = "drive name:";
|
|
||||||
|
|
||||||
if (strncmp(line, drive_name_string, sizeof(drive_name_string) - 1) == 0) {
|
|
||||||
char *device_name;
|
|
||||||
|
|
||||||
device_name = strtok(skip_whitespace(line + sizeof(drive_name_string) - 1), " \t\n");
|
|
||||||
while (device_name && device_name[0]) {
|
|
||||||
ma = mi = -1;
|
|
||||||
dev_get_major_minor(device_name, &ma, &mi);
|
|
||||||
uuidcache_check_device(device_name, ma, mi, 1);
|
|
||||||
device_name = strtok(NULL, " \t\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(proccd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -297,8 +107,11 @@ uuidcache_init(void)
|
|||||||
if (uuidCache)
|
if (uuidCache)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uuidcache_init_partitions();
|
recursive_action("/dev", ACTION_RECURSE,
|
||||||
uuidcache_init_cdroms();
|
uuidcache_check_device, /* file_action */
|
||||||
|
NULL, /* dir_action */
|
||||||
|
NULL, /* userData */
|
||||||
|
0 /* depth */);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UUID 1
|
#define UUID 1
|
||||||
|
@ -190,19 +190,14 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* open volume by device node */
|
/* open volume by device node */
|
||||||
struct volume_id *volume_id_open_node(const char *path)
|
struct volume_id *volume_id_open_node(int fd)
|
||||||
{
|
{
|
||||||
struct volume_id *id;
|
struct volume_id *id;
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
return NULL;
|
|
||||||
id = xzalloc(sizeof(struct volume_id));
|
id = xzalloc(sizeof(struct volume_id));
|
||||||
id->fd = fd;
|
id->fd = fd;
|
||||||
///* close fd on device close */
|
///* close fd on device close */
|
||||||
//id->fd_close = 1;
|
//id->fd_close = 1;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ struct volume_id {
|
|||||||
// int fd_close:1;
|
// int fd_close:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct volume_id *volume_id_open_node(const char *path);
|
struct volume_id *volume_id_open_node(int fd);
|
||||||
int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size);
|
int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size);
|
||||||
void free_volume_id(struct volume_id *id);
|
void free_volume_id(struct volume_id *id);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user