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:
parent
cb7c281b8d
commit
c506c4087e
@ -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 \
|
||||
|
@ -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
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user