]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fdisk: API: add label probing functionality
authorDavidlohr Bueso <dave@gnu.org>
Sun, 8 Jul 2012 21:40:27 +0000 (23:40 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 16 Jul 2012 15:59:52 +0000 (17:59 +0200)
This patch sets the initial layout for label specific operations. A
new fdisk_label structure is created that will hold all these ops,
like new, delete, write and probe, among others. For now only probing
is implemented. Once this design is established, a copy of the probed
label will be copied to the main context structure, where calling the
specific functions will save 'disklabel' checks. Debugging support is
added as well.

This patch passes regression tests and manually passes bsd, sun, dos
and sgi labels probes.

Reviewed-by: Petr Uzel <petr.uzel@suse.cz>
Signed-off-by: Davidlohr Bueso <dave@gnu.org>
15 files changed:
fdisks/fdisk.c
fdisks/fdisk.h
fdisks/fdiskaixlabel.c
fdisks/fdiskaixlabel.h
fdisks/fdiskbsdlabel.c
fdisks/fdiskbsdlabel.h
fdisks/fdiskdoslabel.c
fdisks/fdiskdoslabel.h
fdisks/fdiskmaclabel.c
fdisks/fdiskmaclabel.h
fdisks/fdisksgilabel.c
fdisks/fdisksgilabel.h
fdisks/fdisksunlabel.c
fdisks/fdisksunlabel.h
fdisks/utils.c

index 4d5ab02cebdf07b88c2d30981ae34680a8c8e52f..5e06b8b3eb1b496520ee440f14f99ad64f1620b5 100644 (file)
@@ -520,27 +520,6 @@ update_sector_offset(struct fdisk_context *cxt)
  *    1: I/O error
  */
 static int get_boot(struct fdisk_context *cxt, int try_only) {
-
-       disklabel = ANY_LABEL;
-       update_units(cxt);
-
-       if (!check_dos_label(cxt))
-               if (check_sun_label(cxt) || check_sgi_label(cxt) || check_aix_label(cxt)
-                   || check_mac_label(cxt))
-                       return 0;
-
-       if (check_osf_label(cxt)) {
-               /* intialize partitions for BSD as well */
-               dos_init(cxt);
-               if (!valid_part_table_flag(cxt->mbr)) {
-                       disklabel = OSF_LABEL;
-                       return 0;
-               }
-               printf(_("This disk has both DOS and BSD magic.\n"
-                        "Give the 'b' command to go to BSD mode.\n"));
-               return 0;
-       }
-
        if (disklabel == ANY_LABEL) {
                if (try_only)
                        return -1;
index 51a63b228adbe7127a84353183a897e431b285a1..64a8147e651b87348fe73bbf96b19b61a754c1f2 100644 (file)
@@ -37,6 +37,7 @@
 #define FDISK_DEBUG_CONTEXT    (1 << 2)
 #define FDISK_DEBUG_TOPOLOGY    (1 << 3)
 #define FDISK_DEBUG_GEOMETRY    (1 << 4)
+#define FDISK_DEBUG_LABEL       (1 << 5)
 #define FDISK_DEBUG_ALL                0xFFFF
 
 # define ON_DBG(m, x)  do { \
@@ -125,6 +126,24 @@ struct fdisk_context {
        struct fdisk_geometry geom;
 };
 
+/*
+ * Label specific operations
+ */
+struct fdisk_label {
+       const char *name;
+       int (*probe)(struct fdisk_context *cxt);
+};
+
+/*
+ * labels
+ */
+extern const struct fdisk_label aix_label;
+extern const struct fdisk_label dos_label;
+extern const struct fdisk_label bsd_label;
+extern const struct fdisk_label mac_label;
+extern const struct fdisk_label sun_label;
+extern const struct fdisk_label sgi_label;
+
 extern struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly);
 extern int fdisk_dev_has_topology(struct fdisk_context *cxt);
 extern int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt);
index 438647ba8ddf41a3ade60e08ad921ec7263c3573..474a177493c12e9eccfa68442235653e656a7fec 100644 (file)
@@ -49,7 +49,7 @@ aix_nolabel(struct fdisk_context *cxt)
     return;
 }
 
-int check_aix_label(struct fdisk_context *cxt)
+static int check_aix_label(struct fdisk_context *cxt)
 {
     if (aixlabel->magic != AIX_LABEL_MAGIC &&
        aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED) {
@@ -65,3 +65,9 @@ int check_aix_label(struct fdisk_context *cxt)
     aix_nolabel(cxt);          /* %% */
     return 1;
 }
+
+const struct fdisk_label aix_label =
+{
+       .name = "aix",
+       .probe = check_aix_label
+};
index bd4cb27811b3f4c240195c9355d75d07dd71b090..ea7aebd70a2f0ef8767aab4c79d9f05a952096c3 100644 (file)
@@ -22,6 +22,4 @@ typedef struct {
 
 /* fdiskaixlabel.c */
 extern struct  systypes aix_sys_types[];
-extern int     check_aix_label(struct fdisk_context *cxt);
-
 #endif /* FDISK_AIX_LABEL_H */
index 53c8ad512a1017dc31c551ac24386b73e987ff2f..9ede3ef761514689efb8177a5a18ca70b5804f00 100644 (file)
@@ -109,7 +109,7 @@ static struct xbsd_disklabel xbsd_dlabel;
  * Note: often reformatting with DOS-type label leaves the BSD magic,
  * so this does not mean that there is a BSD disk label.
  */
-int
+static int
 check_osf_label(struct fdisk_context *cxt) {
        if (xbsd_readlabel (cxt, NULL, &xbsd_dlabel) == 0)
                return 0;
@@ -845,3 +845,9 @@ alpha_bootblock_checksum (char *boot)
   dp[63] = sum;
 }
 #endif /* __alpha__ */
+
+const struct fdisk_label bsd_label =
+{
+       .name = "bsd",
+       .probe = check_osf_label
+};
index 3a198fefccd40d0905bed7d6d8818cb41c021f44..ab6877eaac41ddc4d3760b0d855b4e07f77ac721 100644 (file)
@@ -239,7 +239,6 @@ static struct systypes xbsd_fstypes[] = {
 #define        BSD_D_DOSPART   0x20            /* within MSDOS partition */
 
 extern void bsd_command_prompt(struct fdisk_context *cxt);
-extern int check_osf_label(struct fdisk_context *cxt);
 extern int btrydev(struct fdisk_context *cxt);
 extern void xbsd_print_disklabel(struct fdisk_context *cxt, int);
 
index a72a432c1e8c1d1ec7b2cd8c7774f29eefbfbf92..27536da38d325cf4e08debdbb9b9c03abbd0e154 100644 (file)
@@ -316,7 +316,7 @@ void dos_delete_partition(int i)
        }
 }
 
-int check_dos_label(struct fdisk_context *cxt)
+static int check_dos_label(struct fdisk_context *cxt)
 {
        int i;
 
@@ -680,3 +680,9 @@ void dos_write_table(struct fdisk_context *cxt)
                }
        }
 }
+
+const struct fdisk_label dos_label =
+{
+       .name = "dos",
+       .probe = check_dos_label,
+};
index f64a4cedda0bd4c95cdac5171f7e630987a61f53..608e3f700373037dbb67b1369cb703990aa8b7ef 100644 (file)
@@ -47,7 +47,6 @@ extern void create_doslabel(struct fdisk_context *cxt);
 extern void dos_print_mbr_id(struct fdisk_context *cxt);
 extern void dos_set_mbr_id(struct fdisk_context *cxt);
 extern void dos_delete_partition(int i);
-extern int check_dos_label(struct fdisk_context *cxt);
 extern int is_dos_partition(int t);
 extern void dos_init(struct fdisk_context *cxt);
 extern void dos_add_partition(struct fdisk_context *cxt, int n, int sys);
index 561189a898e3a10c45acc03f0993fdf065de1677..1b826609d40ceddb95411cd047f384367d7c2604 100644 (file)
@@ -47,7 +47,7 @@ mac_nolabel(struct fdisk_context *cxt)
     return;
 }
 
-int
+static int
 check_mac_label(struct fdisk_context *cxt)
 {
        /*
@@ -80,3 +80,9 @@ IS_MAC:
     mac_nolabel(cxt);          /* %% */
     return 1;
 }
+
+const struct fdisk_label mac_label =
+{
+       .name = "mac",
+       .probe = check_mac_label
+};
index 8d9430af5c700fa445e63502fb478c77eb5d2bdd..9966849cc7ac9ce05b70271bd2b58b96784ed841 100644 (file)
@@ -33,6 +33,5 @@ typedef struct {
 /* fdiskmaclabel.c */
 extern struct  systypes mac_sys_types[];
 extern void    mac_nolabel(struct fdisk_context *cxt);
-extern int     check_mac_label(struct fdisk_context *cxt);
 
 #endif /* FDISK_MAC_LABEL_H */
index 09b3ca5f61b5c50ac8daf54a33d60fe3005210a0..32dae78b0c48c09b5c20aa5450f2080771289631 100644 (file)
@@ -127,7 +127,7 @@ two_s_complement_32bit_sum(unsigned int *base, int size /* in bytes */) {
        return sum;
 }
 
-int
+static int
 check_sgi_label(struct fdisk_context *cxt) {
        if (sizeof(sgilabel) > 512) {
                fprintf(stderr,
@@ -877,3 +877,9 @@ fill_sgiinfo(void)
        strcpy((char *) info->installer, "Sfx version 5.3, Oct 18, 1994");
        return info;
 }
+
+const struct fdisk_label sgi_label =
+{
+       .name = "sgi",
+       .probe = check_sgi_label
+};
index 0c76edb91f0dc86d0af085d5e35d167d9f1624d2..f6b88e83ca606c2f1294c15c58639b4b114b7e83 100644 (file)
@@ -111,7 +111,6 @@ typedef struct {
 
 /* fdisksgilabel.c */
 extern struct  systypes sgi_sys_types[];
-extern int     check_sgi_label(struct fdisk_context *cxt);
 extern void    sgi_list_table( struct fdisk_context *cxt, int xtra );
 extern int  sgi_change_sysid(struct fdisk_context *cxt, int i, int sys);
 extern unsigned int    sgi_get_start_sector(struct fdisk_context *cxt, int i );
index 985a976e5fd5036e34997c7e837f7f533db4051e..d1f60541353b4b81ee1930a202bd8b2dfb7e0af9 100644 (file)
@@ -78,7 +78,7 @@ static void init(void)
        partitions = SUN_NUM_PARTITIONS;
 }
 
-int check_sun_label(struct fdisk_context *cxt)
+static int check_sun_label(struct fdisk_context *cxt)
 {
        unsigned short *ush;
        int csum;
@@ -642,3 +642,9 @@ int sun_get_sysid(struct fdisk_context *cxt, int i)
 {
        return SSWAP16(sunlabel->part_tags[i].tag);
 }
+
+const struct fdisk_label sun_label =
+{
+       .name = "sun",
+       .probe = check_sun_label,
+};
index abb29c3b50ad97bb750336a6bf1a6af72c2ff752..9779e22f3392a14d38883b86b2c867a0f735c0b0 100644 (file)
@@ -77,7 +77,6 @@ struct sun_disk_label {
 
 /* fdisksunlabel.c */
 extern struct systypes sun_sys_types[];
-extern int check_sun_label(struct fdisk_context *cxt);
 extern void create_sunlabel(struct fdisk_context *cxt);
 extern void sun_delete_partition(struct fdisk_context *cxt, int i);
 extern int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys);
index 04ad0a56eb2e410c5972d16c40c2e0c4f3fcdcd8..94a080fb3391a2e66b9004d0edaff8a5b14c44a4 100644 (file)
 
 int fdisk_debug_mask;
 
+/*
+ * label probing functions
+ */
+static const struct fdisk_label *labels[] =
+{
+       &bsd_label,
+       &dos_label,
+       &sgi_label,
+       &sun_label,
+       &aix_label,
+       &mac_label,
+};
+
+static int __probe_labels(struct fdisk_context *cxt)
+{
+       int i, rc = 0;
+
+       disklabel = ANY_LABEL;
+       update_units(cxt);
+
+       for (i = 0; i < ARRAY_SIZE(labels); i++) {
+               rc = labels[i]->probe(cxt);
+               if (rc) {
+                       DBG(LABEL, dbgprint("detected a %s label\n",
+                                           labels[i]->name));
+                       goto done;
+               }
+       }
+
+done:
+       return rc;
+}
+
 static int __init_mbr_buffer(struct fdisk_context *cxt)
 {
        DBG(TOPOLOGY, dbgprint("initialize MBR buffer"));
@@ -259,6 +292,8 @@ struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int rea
        __discover_topology(cxt);
        __discover_geometry(cxt);
 
+       __probe_labels(cxt);
+
        DBG(CONTEXT, dbgprint("context initialized for %s [%s]",
                              fname, readonly ? "READ-ONLY" : "READ-WRITE"));
        return cxt;