[virt-tools-list] [libosinfo 3/4] Add osinfo_media_new_from_location()

Daniel P. Berrange berrange at redhat.com
Tue Aug 30 15:38:44 UTC 2011


On Tue, Aug 23, 2011 at 12:31:25AM +0300, Zeeshan Ali (Khattak) wrote:
> From: "Zeeshan Ali (Khattak)" <zeeshanak at gnome.org>
> 
> Add API to create a OsinfoMedia object, given an installation media
> location. This includes moving of installation media errors to
> osinfo_media module and rename from OsinfoInstallMediaError to
> OsinfoMediaError.
> 
> Some application/libraries will want to be able to get basic information
> about an installation media without having to load the whole metadata DB.
> ---
>  osinfo/libosinfo.syms |    3 +-
>  osinfo/osinfo_db.c    |  148 +++++------------------------------------
>  osinfo/osinfo_db.h    |   24 -------
>  osinfo/osinfo_media.c |  176 +++++++++++++++++++++++++++++++++++++++++++++++++
>  osinfo/osinfo_media.h |   28 ++++++++
>  5 files changed, 224 insertions(+), 155 deletions(-)
> 
> diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
> index 2b2a03e..e64156a 100644
> --- a/osinfo/libosinfo.syms
> +++ b/osinfo/libosinfo.syms
> @@ -1,7 +1,6 @@
>  LIBOSINFO_0.0.1 {
>      global:
>  	osinfo_db_get_type;
> -	osinfo_install_media_error_quark;
>  	osinfo_db_new;
>  	osinfo_db_get_platform;
>  	osinfo_db_get_device;
> @@ -142,7 +141,9 @@ LIBOSINFO_0.0.1 {
>  	osinfo_deploymentlist_new_intersection;
>  	osinfo_deploymentlist_new_union;
>  	osinfo_media_get_type;
> +	osinfo_media_error_quark;
>  	osinfo_media_new;
> +	osinfo_media_new_from_location;
>  	osinfo_media_get_architecture;
>  	osinfo_media_get_url;
>  	osinfo_media_get_volume_id;
> diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
> index d8e6b7c..42ca7eb 100644
> --- a/osinfo/osinfo_db.c
> +++ b/osinfo/osinfo_db.c
> @@ -25,43 +25,6 @@
>  #include <osinfo/osinfo.h>
>  #include <gio/gio.h>
>  #include <string.h>
> -#include <stdlib.h>
> -
> -#define MAX_VOLUME 32
> -#define MAX_SYSTEM 32
> -#define MAX_PUBLISHER 128
> -
> -#define PVD_OFFSET 0x00008000
> -#define BOOTABLE_TAG "EL TORITO SPECIFICATION"
> -
> -typedef struct _PrimaryVolumeDescriptor PrimaryVolumeDescriptor;
> -
> -struct _PrimaryVolumeDescriptor {
> -    guint8 ignored[8];
> -    gchar  system[MAX_SYSTEM];       /* System ID */
> -    gchar  volume[MAX_VOLUME];       /* Volume ID */
> -    guint8 ignored2[246];
> -    gchar  publisher[MAX_PUBLISHER]; /* Publisher ID */
> -    guint8 ignored3[1602];
> -};
> -
> -typedef struct _SupplementaryVolumeDescriptor SupplementaryVolumeDescriptor;
> -
> -struct _SupplementaryVolumeDescriptor {
> -    guint8 ignored[7];
> -    gchar  system[MAX_SYSTEM]; /* System ID */
> -};
> -
> -GQuark
> -osinfo_install_media_error_quark (void)
> -{
> -    static GQuark quark = 0;
> -
> -    if (!quark)
> -        quark = g_quark_from_static_string ("osinfo-install-media-error");
> -
> -    return quark;
> -}
>  
>  G_DEFINE_TYPE (OsinfoDb, osinfo_db, G_TYPE_OBJECT);
>  
> @@ -377,98 +340,24 @@ OsinfoOs *osinfo_db_guess_os_from_location(OsinfoDb *db,
>                                             GError **error)
>  {
>      OsinfoOs *ret = NULL;
> -    PrimaryVolumeDescriptor pvd;
> -    SupplementaryVolumeDescriptor svd;
> -    GFile *file;
> -    GFileInputStream *stream;
> +    OsinfoMedia *media;
>      GList *oss = NULL;
>      GList *os_iter;
> +    const gchar *media_volume;
> +    const gchar *media_system;
> +    const gchar *media_publisher;
>  
>      g_return_val_if_fail(OSINFO_IS_DB(db), NULL);
>      g_return_val_if_fail(location != NULL, NULL);
>      g_return_val_if_fail(error == NULL || *error == NULL, NULL);
>  
> -    file = g_file_new_for_commandline_arg(location);
> -    stream = g_file_read(file, NULL, error);
> -    if (error != NULL && *error != NULL) {
> -        g_prefix_error(error, "Failed to open file");
> -
> -        goto EXIT;
> -    }
> -
> -    memset(&pvd, 0, sizeof(pvd));
> -    if (g_input_stream_skip(G_INPUT_STREAM(stream),
> -                            PVD_OFFSET,
> -                            cancellable,
> -                            error) < sizeof(pvd)) {
> -        if (*error)
> -            g_prefix_error(error, "Failed to skip %d bytes", PVD_OFFSET);
> -        else
> -            g_set_error(error,
> -                         OSINFO_INSTALL_MEDIA_ERROR,
> -                         OSINFO_INSTALL_MEDIA_ERROR_NO_DESCRIPTORS,
> -                         "No volume descriptors");
> -
> +    media = osinfo_media_new_from_location (location, cancellable, error);
> +    if (*error != NULL)
>          goto EXIT;
> -    }
> -
> -    if (g_input_stream_read(G_INPUT_STREAM(stream),
> -                            &pvd,
> -                            sizeof(pvd),
> -                            cancellable,
> -                            error) < sizeof(pvd)) {
> -        if (*error)
> -            g_prefix_error(error, "Failed to read primary volume descriptor");
> -        else
> -            g_set_error(error,
> -                        OSINFO_INSTALL_MEDIA_ERROR,
> -                        OSINFO_INSTALL_MEDIA_ERROR_NO_PVD,
> -                        "Primary volume descriptor unavailable");
> -
> -        goto EXIT;
> -    }
> -
> -    pvd.volume[MAX_VOLUME - 1] = 0;
> -    pvd.system[MAX_SYSTEM - 1] = 0;
> -    pvd.publisher[MAX_PUBLISHER - 1] = 0;
> -
> -    if (pvd.volume[0] && (pvd.system[0] == 0 && pvd.publisher[0] == 0)) {
> -        g_set_error(error,
> -                    OSINFO_INSTALL_MEDIA_ERROR,
> -                    OSINFO_INSTALL_MEDIA_ERROR_INSUFFIENT_METADATA,
> -                    "Insufficient metadata on installation media");
> -
> -        goto EXIT;
> -    }
> -
> -    memset(&svd, 0, sizeof(svd));
> -    if (g_input_stream_read(G_INPUT_STREAM(stream),
> -                            &svd,
> -                            sizeof(svd),
> -                            cancellable,
> -                            error) < sizeof(svd)) {
> -        if (*error)
> -            g_prefix_error(error,
> -                           "Failed to read supplementary volume descriptor");
> -        else
> -            g_set_error(error,
> -                        OSINFO_INSTALL_MEDIA_ERROR,
> -                        OSINFO_INSTALL_MEDIA_ERROR_NO_SVD,
> -                        "Supplementary volume descriptor unavailable");
> -
> -        goto EXIT;
> -    }
>  
> -    svd.system[MAX_SYSTEM - 1] = 0;
> -
> -    if (strncmp(BOOTABLE_TAG, svd.system, sizeof(BOOTABLE_TAG) != 0)) {
> -        g_set_error(error,
> -                    OSINFO_INSTALL_MEDIA_ERROR,
> -                    OSINFO_INSTALL_MEDIA_ERROR_NOT_BOOTABLE,
> -                    "Install media is not bootable");
> -
> -        goto EXIT;
> -    }
> +    media_volume = osinfo_media_get_volume_id(media);
> +    media_system = osinfo_media_get_system_id(media);
> +    media_publisher = osinfo_media_get_publisher_id(media);
>  
>      oss = osinfo_list_get_elements(OSINFO_LIST(db->priv->oses));
>      for (os_iter = oss; os_iter; os_iter = os_iter->next) {
> @@ -478,14 +367,14 @@ OsinfoOs *osinfo_db_guess_os_from_location(OsinfoDb *db,
>          GList *media_iter;
>  
>          for (media_iter = medias; media_iter; media_iter = media_iter->next) {
> -            OsinfoMedia *media = OSINFO_MEDIA(media_iter->data);
> -            const gchar *media_volume = osinfo_media_get_volume_id(media);
> -            const gchar *media_system = osinfo_media_get_system_id(media);
> -            const gchar *media_publisher = osinfo_media_get_publisher_id(media);
> -
> -            if (str_contains(pvd.volume, media_volume) &&
> -                (str_contains(pvd.system, media_system) ||
> -                 str_contains(pvd.publisher, media_publisher))) {
> +            OsinfoMedia *os_media = OSINFO_MEDIA(media_iter->data);
> +            const gchar *os_volume = osinfo_media_get_volume_id(os_media);
> +            const gchar *os_system = osinfo_media_get_system_id(os_media);
> +            const gchar *os_publisher = osinfo_media_get_publisher_id(os_media);
> +
> +            if (str_contains(media_volume, os_volume) &&
> +                (str_contains(media_system, os_system) ||
> +                 str_contains(media_publisher, os_publisher))) {
>                  ret = os;
>                  break;
>              }
> @@ -500,8 +389,7 @@ OsinfoOs *osinfo_db_guess_os_from_location(OsinfoDb *db,
>  
>  EXIT:
>      g_list_free(oss);
> -    g_object_unref(stream);
> -    g_object_unref(file);
> +    g_clear_object(&media);
>  
>      return ret;
>  }
> diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
> index 3f56de1..f3ba37e 100644
> --- a/osinfo/osinfo_db.h
> +++ b/osinfo/osinfo_db.h
> @@ -34,30 +34,6 @@
>  #ifndef __OSINFO_DB_H__
>  #define __OSINFO_DB_H__
>  
> -GQuark
> -osinfo_install_media_error_quark (void) G_GNUC_CONST;
> -
> -#define OSINFO_INSTALL_MEDIA_ERROR (osinfo_install_media_error_quark ())
> -
> -/**
> - * OsinfoInstallMediaError:
> - * @OSINFO_INSTALL_MEDIA_ERROR_NO_DESCRIPTORS: No descriptors.
> - * @OSINFO_INSTALL_MEDIA_ERROR_INSUFFIENT_METADATA: Not enough metadata.
> - * @OSINFO_INSTALL_MEDIA_ERROR_NOT_BOOTABLE: Install media not bootable.
> - * @OSINFO_INSTALL_MEDIA_ERROR_NO_PVD: No Primary volume descriptor.
> - * @OSINFO_INSTALL_MEDIA_ERROR_NO_SVD: No supplementary volume descriptor.
> - *
> - * #GError codes used for errors in the #OSINFO_INSTALL_MEDIA_ERROR domain, during
> - * reading of data from install media for detection of OS.
> - */
> -typedef enum {
> -    OSINFO_INSTALL_MEDIA_ERROR_NO_DESCRIPTORS,
> -    OSINFO_INSTALL_MEDIA_ERROR_NO_PVD,
> -    OSINFO_INSTALL_MEDIA_ERROR_NO_SVD,
> -    OSINFO_INSTALL_MEDIA_ERROR_INSUFFIENT_METADATA,
> -    OSINFO_INSTALL_MEDIA_ERROR_NOT_BOOTABLE
> -} OsinfoInstallMediaError;
> -
>  /*
>   * Type macros.
>   */
> diff --git a/osinfo/osinfo_media.c b/osinfo/osinfo_media.c
> index 5af6d67..9f44806 100644
> --- a/osinfo/osinfo_media.c
> +++ b/osinfo/osinfo_media.c
> @@ -24,6 +24,45 @@
>   */
>  
>  #include <osinfo/osinfo.h>
> +#include <gio/gio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#define MAX_VOLUME 32
> +#define MAX_SYSTEM 32
> +#define MAX_PUBLISHER 128
> +
> +#define PVD_OFFSET 0x00008000
> +#define BOOTABLE_TAG "EL TORITO SPECIFICATION"
> +
> +typedef struct _PrimaryVolumeDescriptor PrimaryVolumeDescriptor;
> +
> +struct _PrimaryVolumeDescriptor {
> +    guint8 ignored[8];
> +    gchar  system[MAX_SYSTEM];       /* System ID */
> +    gchar  volume[MAX_VOLUME];       /* Volume ID */
> +    guint8 ignored2[246];
> +    gchar  publisher[MAX_PUBLISHER]; /* Publisher ID */
> +    guint8 ignored3[1602];
> +};
> +
> +typedef struct _SupplementaryVolumeDescriptor SupplementaryVolumeDescriptor;
> +
> +struct _SupplementaryVolumeDescriptor {
> +    guint8 ignored[7];
> +    gchar  system[MAX_SYSTEM]; /* System ID */
> +};
> +
> +GQuark
> +osinfo_media_error_quark (void)
> +{
> +    static GQuark quark = 0;
> +
> +    if (!quark)
> +        quark = g_quark_from_static_string ("osinfo-media-error");
> +
> +    return quark;
> +}
>  
>  G_DEFINE_TYPE (OsinfoMedia, osinfo_media, OSINFO_TYPE_ENTITY);
>  
> @@ -88,6 +127,143 @@ OsinfoMedia *osinfo_media_new(const gchar *id,
>  }
>  
>  /**
> + * osinfo_media_new_from_location:
> + * @location: the location of an installation media
> + * @cancellable (allow-none): a #GCancellable, or %NULL
> + * @error: The location where to store any error, or %NULL
> + *
> + * Creates a new #OsinfoMedia for installation media at @location. The @location
> + * could be any URI that GIO can handle or a local path.
> + *
> + * NOTE: Currently this only works for ISO images/devices.
> + *
> + * Returns: (transfer full): a new #OsinfoMedia , or NULL on error
> + */
> +OsinfoMedia *osinfo_media_new_from_location(const gchar *location,
> +                                            GCancellable *cancellable,
> +                                            GError **error)
> +{
> +    OsinfoMedia *ret = NULL;
> +    PrimaryVolumeDescriptor pvd;
> +    SupplementaryVolumeDescriptor svd;
> +    GFile *file;
> +    GFileInputStream *stream;
> +    gchar *uri;
> +
> +    g_return_val_if_fail(location != NULL, NULL);
> +    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
> +
> +    file = g_file_new_for_commandline_arg(location);
> +    stream = g_file_read(file, NULL, error);
> +    if (error != NULL && *error != NULL) {
> +        g_prefix_error(error, "Failed to open file");
> +
> +        goto EXIT;
> +    }
> +
> +    memset(&pvd, 0, sizeof(pvd));
> +    if (g_input_stream_skip(G_INPUT_STREAM(stream),
> +                            PVD_OFFSET,
> +                            cancellable,
> +                            error) < sizeof(pvd)) {
> +        if (*error)
> +            g_prefix_error(error, "Failed to skip %d bytes", PVD_OFFSET);
> +        else
> +            g_set_error(error,
> +                         OSINFO_MEDIA_ERROR,
> +                         OSINFO_MEDIA_ERROR_NO_DESCRIPTORS,
> +                         "No volume descriptors");
> +
> +        goto EXIT;
> +    }
> +
> +    if (g_input_stream_read(G_INPUT_STREAM(stream),
> +                            &pvd,
> +                            sizeof(pvd),
> +                            cancellable,
> +                            error) < sizeof(pvd)) {
> +        if (*error)
> +            g_prefix_error(error, "Failed to read primary volume descriptor");
> +        else
> +            g_set_error(error,
> +                        OSINFO_MEDIA_ERROR,
> +                        OSINFO_MEDIA_ERROR_NO_PVD,
> +                        "Primary volume descriptor unavailable");
> +
> +        goto EXIT;
> +    }
> +
> +    pvd.volume[MAX_VOLUME - 1] = 0;
> +    pvd.system[MAX_SYSTEM - 1] = 0;
> +    pvd.publisher[MAX_PUBLISHER - 1] = 0;
> +
> +    if (pvd.volume[0] && (pvd.system[0] == 0 && pvd.publisher[0] == 0)) {
> +        g_set_error(error,
> +                    OSINFO_MEDIA_ERROR,
> +                    OSINFO_MEDIA_ERROR_INSUFFIENT_METADATA,
> +                    "Insufficient metadata on installation media");
> +
> +        goto EXIT;
> +    }
> +
> +    memset(&svd, 0, sizeof(svd));
> +    if (g_input_stream_read(G_INPUT_STREAM(stream),
> +                            &svd,
> +                            sizeof(svd),
> +                            cancellable,
> +                            error) < sizeof(svd)) {
> +        if (*error)
> +            g_prefix_error(error,
> +                           "Failed to read supplementary volume descriptor");
> +        else
> +            g_set_error(error,
> +                        OSINFO_MEDIA_ERROR,
> +                        OSINFO_MEDIA_ERROR_NO_SVD,
> +                        "Supplementary volume descriptor unavailable");
> +
> +        goto EXIT;
> +    }
> +
> +    svd.system[MAX_SYSTEM - 1] = 0;
> +
> +    if (strncmp(BOOTABLE_TAG, svd.system, sizeof(BOOTABLE_TAG) != 0)) {
> +        g_set_error(error,
> +                    OSINFO_MEDIA_ERROR,
> +                    OSINFO_MEDIA_ERROR_NOT_BOOTABLE,
> +                    "Install media is not bootable");
> +
> +        goto EXIT;
> +    }
> +
> +    uri = g_file_get_uri(file);
> +    ret = g_object_new(OSINFO_TYPE_MEDIA,
> +                       "id", uri,
> +                       NULL);
> +    osinfo_entity_set_param(OSINFO_ENTITY(ret),
> +                            OSINFO_MEDIA_PROP_URL,
> +                            uri);
> +    g_free(uri);
> +    if (pvd.volume[0] != 0)
> +        osinfo_entity_set_param(OSINFO_ENTITY(ret),
> +                                OSINFO_MEDIA_PROP_VOLUME_ID,
> +                                pvd.volume);
> +    if (pvd.system[0] != 0)
> +        osinfo_entity_set_param(OSINFO_ENTITY(ret),
> +                                OSINFO_MEDIA_PROP_SYSTEM_ID,
> +                                pvd.system);
> +    if (pvd.publisher[0] != 0)
> +        osinfo_entity_set_param(OSINFO_ENTITY(ret),
> +                                OSINFO_MEDIA_PROP_PUBLISHER_ID,
> +                                pvd.publisher);
> +
> +EXIT:
> +    g_object_unref(stream);
> +    g_object_unref(file);
> +
> +    return ret;
> +}
> +
> +/**
>   * osinfo_entity_get_architecture:
>   * @media: a #OsinfoMedia instance
>   *
> diff --git a/osinfo/osinfo_media.h b/osinfo/osinfo_media.h
> index 4552da9..9d68c6e 100644
> --- a/osinfo/osinfo_media.h
> +++ b/osinfo/osinfo_media.h
> @@ -24,11 +24,36 @@
>   */
>  
>  #include <glib-object.h>
> +#include <gio/gio.h>
>  #include <osinfo/osinfo_entity.h>
>  
>  #ifndef __OSINFO_MEDIA_H__
>  #define __OSINFO_MEDIA_H__
>  
> +GQuark
> +osinfo_media_error_quark (void) G_GNUC_CONST;
> +
> +#define OSINFO_MEDIA_ERROR (osinfo_media_error_quark ())
> +
> +/**
> + * OsinfoMediaError:
> + * @OSINFO_MEDIA_ERROR_NO_DESCRIPTORS: No descriptors.
> + * @OSINFO_MEDIA_ERROR_INSUFFIENT_METADATA: Not enough metadata.
> + * @OSINFO_MEDIA_ERROR_NOT_BOOTABLE: Install media not bootable.
> + * @OSINFO_MEDIA_ERROR_NO_PVD: No Primary volume descriptor.
> + * @OSINFO_MEDIA_ERROR_NO_SVD: No supplementary volume descriptor.
> + *
> + * #GError codes used for errors in the #OSINFO_MEDIA_ERROR domain, during
> + * reading of data from install media location.
> + */
> +typedef enum {
> +    OSINFO_MEDIA_ERROR_NO_DESCRIPTORS,
> +    OSINFO_MEDIA_ERROR_NO_PVD,
> +    OSINFO_MEDIA_ERROR_NO_SVD,
> +    OSINFO_MEDIA_ERROR_INSUFFIENT_METADATA,
> +    OSINFO_MEDIA_ERROR_NOT_BOOTABLE
> +} OsinfoMediaError;
> +
>  /*
>   * Type macros.
>   */
> @@ -73,6 +98,9 @@ struct _OsinfoMediaClass
>  GType osinfo_media_get_type(void);
>  
>  OsinfoMedia *osinfo_media_new(const gchar *id, const gchar *architecture);
> +OsinfoMedia *osinfo_media_new_from_location(const gchar *location,
> +                                            GCancellable *cancellable,
> +                                            GError **error);
>  
>  const gchar *osinfo_media_get_architecture(OsinfoMedia *media);
>  const gchar *osinfo_media_get_url(OsinfoMedia *media);

ACK

Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the virt-tools-list mailing list