chiark / gitweb /
[PATCH] udev_volume_id: fix dasd disklabel reading with -l option
[elogind.git] / extras / volume_id / udev_volume_id.c
index e88445054b22eecc3d2b194ff154dd383faa3752..d3c3fcd505dab49a01a1fc47d967522d0bbcea66 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 #include <ctype.h>
-#include <linux/fs.h>
 #include <sys/ioctl.h>
 
 #include "../../libsysfs/sysfs/libsysfs.h"
-#include "../../udev_lib.h"
+#include "../../udev_utils.h"
 #include "../../logging.h"
-#include "volume_id.h"
-#include "dasdlabel.h"
+#include "volume_id/volume_id.h"
+#include "volume_id/dasd/dasd.h"
+
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
 
 #ifdef LOG
-unsigned char logname[LOGNAME_SIZE];
 void log_message(int level, const char *format, ...)
 {
        va_list args;
@@ -73,36 +74,6 @@ 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"
@@ -112,20 +83,21 @@ int main(int argc, char *argv[])
                            "       -d disk label from main device\n"
                            "\n";
        static const char short_options[] = "htlud";
-       char sysfs_path[SYSFS_PATH_MAX];
+       char sysfs_mnt_path[SYSFS_PATH_MAX];
        char dev_path[SYSFS_PATH_MAX];
        struct sysfs_class_device *class_dev = NULL;
        struct sysfs_class_device *class_dev_parent = NULL;
        struct volume_id *vid = NULL;
        char *devpath;
-       char probe = 'p';
+       char probe_disk_label = 0;
        char print = 'a';
-       char dasd_label[7];
        static char name[VOLUME_ID_LABEL_SIZE];
        int len, i, j;
        unsigned long long size;
        int rc = 1;
 
+       logging_init("udev_volume_id");
+
        while (1) {
                int option;
 
@@ -144,7 +116,7 @@ int main(int argc, char *argv[])
                        print = 'u';
                        continue;
                case 'd':
-                       probe = 'd';
+                       probe_disk_label = 1;
                        continue;
                case 'h':
                case '?':
@@ -160,12 +132,12 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) {
+       if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) {
                printf("error getting sysfs mount path\n");
                goto exit;
        }
 
-       strfieldcpy(dev_path, sysfs_path);
+       strfieldcpy(dev_path, sysfs_mnt_path);
        strfieldcat(dev_path, devpath);
 
        class_dev = sysfs_open_class_device_path(dev_path);
@@ -174,35 +146,28 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       switch(probe) {
-       case 'p' :
-               /* open block device */
+       if (probe_disk_label == 0) {
                vid = open_classdev(class_dev);
                if (vid == NULL)
                        goto exit;
 
-               size = get_size(vid);
+               if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
+                       size = 0;
 
-               if (volume_id_probe(vid, VOLUME_ID_ALL, 0, size) == 0)
+               if (volume_id_probe_all(vid, 0, size) == 0)
                        goto print;
-               break;
-       case 'd' :
+       } else {
                /* 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)
                        vid = open_classdev(class_dev_parent);
                else
-                       vid = open_classdev(class_dev_parent);
+                       vid = open_classdev(class_dev);
                if (vid == NULL)
                        goto exit;
 
-               if (probe_ibm_partition(vid->fd, dasd_label) == 0) {
-                       vid->type = "dasd";
-                       strncpy(vid->label, dasd_label, 6);
-                       vid->label[6] = '\0';
+               if (volume_id_probe_dasd_partition(vid) == 0)
                        goto print;
-               }
-               break;
        }
 
        printf("unknown volume type\n");
@@ -239,7 +204,8 @@ print:
                printf("%s\n", vid->type);
                break;
        case 'l':
-               if (name[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) {
+               if (name[0] == '\0' ||
+                   (vid->usage_id != VOLUME_ID_FILESYSTEM && vid->usage_id != VOLUME_ID_DISKLABEL)) {
                        rc = 2;
                        goto exit;
                }
@@ -253,7 +219,7 @@ print:
                printf("%s\n", vid->uuid);
                break;
        case 'a':
-               printf("F:%s\n", usage_id_name(vid->usage_id));
+               printf("F:%s\n", vid->usage);
                printf("T:%s\n", vid->type);
                printf("V:%s\n", vid->type_version);
                printf("L:%s\n", vid->label);
@@ -268,5 +234,7 @@ exit:
        if (vid != NULL)
                volume_id_close(vid);
 
+       logging_close();
+
        exit(rc);
 }