1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-19 22:50:17 +03:00

[PATCH] update udev_volume_id

Here is an update for the volume_id callout to catch up to the latest
and greatest:

o It is able to skip the label reading of linux raid members, which are
  otherwise recognized as a normal filesystem.

o It reads FAT labels stored in the directory instead of the
  superblock (Windows only writes in the directory).

o The NTFS uuid is the right one now.

o It reads all the Apple HFS(+) formats with the labels.

o UFS volumes are recognized but no labels are extracted.

o We use CFLAGS+=-D_FILE_OFFSET_BITS=64 instead of lsee64() which may fix
  a bug mentioned on the klibc mailing list.

A lot of other new features are only used in HAL and not needed in this
simple callout. But if someone stumbles over it and want's to send a patch
for some exotic formats, we better keep it up to date :)
This commit is contained in:
kay.sievers@vrfy.org 2004-09-05 18:05:36 +02:00 committed by Greg KH
parent cb7c281b8d
commit c506c4087e
4 changed files with 1430 additions and 285 deletions

View File

@ -28,7 +28,11 @@ INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
override CFLAGS+=-Wall -fno-builtin
override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts -Wmissing-declarations \
-Wnested-externs -Wpointer-arith -Wcast-align \
-Wsign-compare
override CFLAGS+=-D_FILE_OFFSET_BITS=64
SYSFS = ../../libsysfs/sysfs_bus.o \
../../libsysfs/sysfs_class.o \

View File

@ -25,6 +25,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include "../../libsysfs/sysfs/libsysfs.h"
#include "../../udev_lib.h"
@ -71,6 +73,36 @@ static struct volume_id *open_classdev(struct sysfs_class_device *class_dev)
return vid;
}
static unsigned long long get_size(struct volume_id *vid)
{
unsigned long long size;
if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
size = 0;
return size;
}
static char *usage_id_name(enum volume_id_usage usage)
{
switch(usage) {
case VOLUME_ID_UNUSED:
return "unused";
case VOLUME_ID_UNPROBED:
return "unprobed";
case VOLUME_ID_OTHER:
return "other";
case VOLUME_ID_PARTITIONTABLE:
return "partitiontable";
case VOLUME_ID_FILESYSTEM:
return "filesystem";
case VOLUME_ID_RAID:
return "raid";
default:
return "unknown type_id";
}
}
int main(int argc, char *argv[])
{
const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n"
@ -80,7 +112,6 @@ int main(int argc, char *argv[])
" -d disk label from main device\n"
"\n";
static const char short_options[] = "htlud";
int option;
char sysfs_path[SYSFS_PATH_MAX];
char dev_path[SYSFS_PATH_MAX];
struct sysfs_class_device *class_dev = NULL;
@ -92,9 +123,12 @@ int main(int argc, char *argv[])
char dasd_label[7];
static char name[VOLUME_ID_LABEL_SIZE];
int len, i, j;
unsigned long long size;
int rc = 1;
while (1) {
int option;
option = getopt(argc, argv, short_options);
if (option == -1)
break;
@ -146,24 +180,26 @@ int main(int argc, char *argv[])
vid = open_classdev(class_dev);
if (vid == NULL)
goto exit;
if (volume_id_probe(vid, ALL) == 0)
size = get_size(vid);
if (volume_id_probe(vid, VOLUME_ID_ALL, 0, size) == 0)
goto print;
break;
case 'd' :
/* if we are on a partition, close it and open main block device */
/* if we are on a partition, open main block device instead */
class_dev_parent = sysfs_get_classdev_parent(class_dev);
if (class_dev_parent != NULL) {
volume_id_close(vid);
if (class_dev_parent != NULL)
vid = open_classdev(class_dev_parent);
} else {
else
vid = open_classdev(class_dev_parent);
}
if (vid == NULL)
goto exit;
if (probe_ibm_partition(vid->fd, dasd_label) == 0) {
vid->fs_name = "dasd";
strncpy(vid->label_string, dasd_label, 6);
vid->label_string[6] = '\0';
vid->type = "dasd";
strncpy(vid->label, dasd_label, 6);
vid->label[6] = '\0';
goto print;
}
break;
@ -174,10 +210,10 @@ int main(int argc, char *argv[])
print:
len = strnlen(vid->label_string, VOLUME_ID_LABEL_SIZE);
len = strnlen(vid->label, VOLUME_ID_LABEL_SIZE);
/* remove trailing spaces */
while (len > 0 && isspace(vid->label_string[len-1]))
while (len > 0 && isspace(vid->label[len-1]))
len--;
name[len] = '\0';
@ -185,14 +221,14 @@ print:
i = 0;
j = 0;
while (j < len) {
switch(vid->label_string[j]) {
switch(vid->label[j]) {
case '/' :
break;
case ' ' :
name[i++] = '_';
break;
default :
name[i++] = vid->label_string[j];
name[i++] = vid->label[j];
}
j++;
}
@ -200,27 +236,29 @@ print:
switch (print) {
case 't':
printf("%s\n", vid->fs_name);
printf("%s\n", vid->type);
break;
case 'l':
if (name[0] == '\0') {
if (name[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) {
rc = 2;
goto exit;
}
printf("%s\n", name);
break;
case 'u':
if (vid->uuid_string[0] == '\0') {
if (vid->uuid[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) {
rc = 2;
goto exit;
}
printf("%s\n", vid->uuid_string);
printf("%s\n", vid->uuid);
break;
case 'a':
printf("T:%s\n", vid->fs_name);
printf("L:%s\n", vid->label_string);
printf("F:%s\n", usage_id_name(vid->usage_id));
printf("T:%s\n", vid->type);
printf("V:%s\n", vid->type_version);
printf("L:%s\n", vid->label);
printf("N:%s\n", name);
printf("U:%s\n", vid->uuid_string);
printf("U:%s\n", vid->uuid);
}
rc = 0;

File diff suppressed because it is too large Load Diff

View File

@ -21,42 +21,72 @@
#ifndef _VOLUME_ID_H_
#define _VOLUME_ID_H_
#define VOLUME_ID_VERSION 004
#define VOLUME_ID_VERSION 022
#define VOLUME_ID_LABEL_SIZE 64
#define VOLUME_ID_UUID_SIZE 16
#define VOLUME_ID_UUID_STRING_SIZE 37
#define VOLUME_ID_PATH_MAX 255
#define VOLUME_ID_FORMAT_SIZE 32
#define VOLUME_ID_PATH_MAX 256
#define VOLUME_ID_PARTITIONS_MAX 16
enum volume_id_usage {
VOLUME_ID_UNUSED,
VOLUME_ID_UNPROBED,
VOLUME_ID_OTHER,
VOLUME_ID_FILESYSTEM,
VOLUME_ID_PARTITIONTABLE,
VOLUME_ID_RAID
};
enum filesystem_type {
ALL,
EXT2,
EXT3,
REISER,
XFS,
JFS,
MSDOS,
VFAT,
UDF,
ISO9660,
NTFS,
SWAP
enum volume_id_type {
VOLUME_ID_ALL,
VOLUME_ID_MSDOSPARTTABLE,
VOLUME_ID_MSDOSEXTENDED,
VOLUME_ID_SWAP,
VOLUME_ID_EXT2,
VOLUME_ID_EXT3,
VOLUME_ID_REISERFS,
VOLUME_ID_XFS,
VOLUME_ID_JFS,
VOLUME_ID_VFAT,
VOLUME_ID_UDF,
VOLUME_ID_ISO9660,
VOLUME_ID_NTFS,
VOLUME_ID_MACPARTMAP,
VOLUME_ID_HFS,
VOLUME_ID_HFSPLUS,
VOLUME_ID_UFS,
VOLUME_ID_LINUX_RAID,
VOLUME_ID_LVM1,
VOLUME_ID_LVM2
};
struct volume_id_partition {
enum volume_id_usage usage_id;
enum volume_id_type type_id;
char *type;
unsigned long long off;
unsigned long long len;
};
struct volume_id {
unsigned char label_raw[VOLUME_ID_LABEL_SIZE];
unsigned int label_raw_len;
char label_string[VOLUME_ID_LABEL_SIZE+1];
unsigned char uuid[VOLUME_ID_UUID_SIZE];
char uuid_string[VOLUME_ID_UUID_STRING_SIZE];
enum filesystem_type fs_type;
char *fs_name;
char label[VOLUME_ID_LABEL_SIZE+1];
unsigned char uuid_raw[VOLUME_ID_UUID_SIZE];
char uuid[VOLUME_ID_UUID_STRING_SIZE];
enum volume_id_usage usage_id;
enum volume_id_type type_id;
char *type;
char type_version[VOLUME_ID_FORMAT_SIZE];
struct volume_id_partition *partitions;
unsigned int partition_count;
int fd;
unsigned char *sbbuf;
unsigned int sbbuf_len;
unsigned char *seekbuf;
unsigned int seekbuf_off;
unsigned long long seekbuf_off;
unsigned int seekbuf_len;
int fd_close;
};
@ -71,7 +101,8 @@ extern struct volume_id *volume_id_open_node(const char *path);
extern struct volume_id *volume_id_open_dev_t(dev_t devt);
/* probe volume for filesystem type and try to read label/uuid */
extern int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type);
extern int volume_id_probe(struct volume_id *id, enum volume_id_type type,
unsigned long long off, unsigned long long size);
/* free allocated device info */
extern void volume_id_close(struct volume_id *id);