Permalink
Browse files

devices/storage: Use udisks2 as primary source for storage info

  • Loading branch information...
ocerman authored and lpereira committed Jan 12, 2019
1 parent 340d04e commit 1eb28cdf81fda7bc748e2ba071e2d222a3287453
Showing with 306 additions and 135 deletions.
  1. +161 −44 hardinfo/udisks2_util.c
  2. +6 −2 includes/udisks2_util.h
  3. +7 −4 modules/devices.c
  4. +132 −85 modules/devices/storage.c
  5. BIN pixmaps/media-floppy.png
@@ -5,6 +5,8 @@
#define UDISKS2_INTERFACE "org.freedesktop.UDisks2"
#define UDISKS2_MANAGER_INTERFACE "org.freedesktop.UDisks2.Manager"
#define UDISKS2_BLOCK_INTERFACE "org.freedesktop.UDisks2.Block"
#define UDISKS2_LOOP_INTERFACE "org.freedesktop.UDisks2.Loop"
#define UDISKS2_PARTITION_INTERFACE "org.freedesktop.UDisks2.Partition"
#define UDISKS2_DRIVE_INTERFACE "org.freedesktop.UDisks2.Drive"
#define UDISKS2_DRIVE_ATA_INTERFACE "org.freedesktop.UDisks2.Drive.Ata"
#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
@@ -32,52 +34,146 @@ GVariant* get_dbus_property(GDBusProxy* proxy, const gchar *interface,
return v;
}

GDBusProxy* get_udisks2_drive_proxy(GDBusConnection *conn, const gchar* blockdev_name) {
// this function works with udisks2 version 2.7.2 or newer
GSList* get_block_dev_paths_from_udisks2(GDBusConnection* conn){
GDBusProxy *proxy;
GVariant *v;
GVariant *options, *v;
GVariantIter *iter;
GError *error = NULL;
gchar *path;
const gchar *drive_path;
GSList *block_paths = NULL;
const gchar *block_path = NULL;

// get block device proxy
path = g_strdup_printf("%s/%s", UDISKS2_BLOCK_DEVICES_PATH, blockdev_name);
proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
UDISKS2_INTERFACE, path,
DBUS_PROPERTIES_INTERFACE, NULL, &error);
g_free(path);
path = NULL;
if (error != NULL) {
UDISKS2_INTERFACE, UDISKS2_MANAGER_OBJ_PATH,
UDISKS2_MANAGER_INTERFACE, NULL, &error);
options = g_variant_new_parsed("@a{sv} { %s: <true> }",
"auth.no_user_interaction");
if (error != NULL){
g_error_free (error);
g_object_unref(proxy);
return NULL;
}

// get drive object path
v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "Drive");
if (v) {
drive_path = g_variant_get_string(v, NULL);
if (strcmp(drive_path, "/") != 0) {
path = g_strdup(drive_path);
}
g_variant_unref(v);
}
v = g_dbus_proxy_call_sync(proxy, "GetBlockDevices",
g_variant_new_tuple(&options, 1),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
g_object_unref(proxy);
proxy = NULL;

if (path == NULL)
if (error != NULL){
g_error_free (error);
return NULL;
}

// get drive proxy
proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
UDISKS2_INTERFACE, path,
DBUS_PROPERTIES_INTERFACE, NULL, &error);
g_free(path);
if (error != NULL) {
g_error_free (error);
g_variant_get(v, "(ao)", &iter);
while (g_variant_iter_loop (iter, "o", &block_path)){
block_paths = g_slist_append(block_paths, g_strdup(block_path));
}

g_variant_iter_free (iter);
g_variant_unref(v);
return block_paths;
}

GSList* get_block_dev_paths_from_sysfs(){
GSList *block_paths = NULL;
GDir *dir;
gchar *path;
const gchar *entry;

dir = g_dir_open("/sys/class/block", 0, NULL);
if (!dir)
return NULL;

while ((entry = g_dir_read_name(dir))) {
path = g_strdup_printf("%s/%s", UDISKS2_BLOCK_DEVICES_PATH, entry);
block_paths = g_slist_append(block_paths, path);
}

return proxy;
g_dir_close(dir);
return block_paths;
}

GSList* udisks2_drives_func_caller(GDBusConnection* conn,
gpointer (*func)(const char*, GDBusProxy*)) {
GDBusProxy *proxy, *drive_proxy;
GVariant *block_v, *v;
GSList *result_list = NULL, *block_dev_list, *node;
GError *error = NULL;
gpointer output;

gchar *block_path = NULL;
const gchar *block_dev, *drive_path = NULL;

if (conn == NULL)
return NULL;

// get block devices
block_dev_list = get_block_dev_paths_from_udisks2(conn);
if (block_dev_list == NULL)
block_dev_list = get_block_dev_paths_from_sysfs();

for (node = block_dev_list; node != NULL; node = node->next) {
block_path = (gchar *)node->data;
proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
NULL, UDISKS2_INTERFACE, block_path,
DBUS_PROPERTIES_INTERFACE, NULL, &error);
if (error){
g_error_free(error);
error = NULL;
continue;
}

// Skip partitions
v = get_dbus_property(proxy, UDISKS2_PARTITION_INTERFACE, "Size");
if (v){
g_variant_unref(v);
g_object_unref(proxy);
continue;
}

// Skip loop devices
v = get_dbus_property(proxy, UDISKS2_LOOP_INTERFACE, "BackingFile");
if (v){
g_variant_unref(v);
g_object_unref(proxy);
continue;
}

block_dev = block_path + strlen(UDISKS2_BLOCK_DEVICES_PATH) + 1;
drive_path = NULL;

// let's find drive proxy
v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "Drive");
if (v){
drive_path = g_variant_get_string(v, NULL);

if (g_strcmp0(drive_path, "/") != 0){
drive_proxy = g_dbus_proxy_new_sync(conn,
G_DBUS_PROXY_FLAGS_NONE, NULL,
UDISKS2_INTERFACE, drive_path,
DBUS_PROPERTIES_INTERFACE, NULL, &error);

if (error == NULL) {
// call requested function
output = func(block_dev, drive_proxy);

if (output != NULL){
result_list = g_slist_append(result_list, output);
}
g_object_unref(drive_proxy);
}
else {
g_error_free(error);
error = NULL;
}
}
g_variant_unref(v);
}
g_object_unref(proxy);
}
g_slist_free_full(block_dev_list, g_free);

return result_list;
}

GDBusConnection* get_udisks2_connection(void) {
@@ -115,39 +211,57 @@ GDBusConnection* get_udisks2_connection(void) {
return conn;
}

udiskd *udiskd_new() {
udiskd* udiskd_new() {
return g_new0(udiskd, 1);
}

void udiskd_free(udiskd *u) {
if (u) {
g_free(u->model);
g_free(u->vendor);
g_free(u->revision);
g_free(u->block_dev);
g_free(u->serial);
g_free(u->connection_bus);
g_free(u->media);
g_free(u->media_compatibility);
g_free(u);
}
}

udiskd *get_udisks2_drive_info(const gchar *blockdev) {
GDBusProxy *drive;
gpointer get_udisks2_drive_info(const char *blockdev, GDBusProxy *drive) {
GVariant *v;
const gchar *str;
udiskd *u;

drive = get_udisks2_drive_proxy(udisks2_conn, blockdev);
if (!drive){
return NULL;
}
udiskd *u = NULL;

u = udiskd_new();
u->block_dev = g_strdup(blockdev);

v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Model");
if (v){
u->model = g_variant_dup_string(v, NULL);
g_variant_unref(v);
}
v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Vendor");
if (v){
u->vendor = g_variant_dup_string(v, NULL);
g_variant_unref(v);
}
v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Revision");
if (v){
u->revision = g_variant_dup_string(v, NULL);
g_variant_unref(v);
}
v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Serial");
if (v){
u->serial = g_variant_dup_string(v, NULL);
g_variant_unref(v);
}
v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "ConnectionBus");
if (v){
u->connection_bus = g_variant_dup_string(v, NULL);
g_variant_unref(v);
}
v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "RotationRate");
if (v){
u->rotation_rate = g_variant_get_int32(v);
@@ -218,14 +332,17 @@ udiskd *get_udisks2_drive_info(const gchar *blockdev) {
g_variant_unref(v);
}
}

g_object_unref(drive);
return u;
}

gboolean udisks2_init(){
udisks2_conn = get_udisks2_connection();
return (udisks2_conn != NULL);
GSList* get_udisks2_all_drives_info(void){
return udisks2_drives_func_caller(udisks2_conn, get_udisks2_drive_info);
}

void udisks2_init(){
if (udisks2_conn == NULL){
udisks2_conn = get_udisks2_connection();
}
}

void udisks2_shutdown(){
@@ -1,6 +1,10 @@
typedef struct udiskd {
gchar *model;
gchar *vendor;
gchar *revision;
gchar *block_dev;
gchar *serial;
gchar *connection_bus;
gboolean ejectable;
gboolean removable;
gint32 rotation_rate;
@@ -14,6 +18,6 @@ typedef struct udiskd {
gint32 smart_temperature;
} udiskd;

gboolean udisks2_init();
void udisks2_init();
void udisks2_shutdown();
udiskd *get_udisks2_drive_info(const gchar *blockdev);
GSList *get_udisks2_all_drives_info();
@@ -38,6 +38,7 @@

#include "devices.h"
#include "dt_util.h"
#include "udisks2_util.h"

gchar *callback_processors();
gchar *callback_gpu();
@@ -616,8 +617,10 @@ void scan_storage(gboolean reload)
g_free(storage_list);
storage_list = g_strdup("");

__scan_ide_devices();
__scan_scsi_devices();
if (!__scan_udisks2_devices()) {
__scan_ide_devices();
__scan_scsi_devices();
}
SCAN_END();
}

@@ -791,14 +794,14 @@ void hi_module_init(void)
init_memory_labels();
init_cups();
sensors_init();
storage_init();
udisks2_init();
}

void hi_module_deinit(void)
{
moreinfo_del_with_prefix("DEV");
sensors_shutdown();
storage_shutdown();
udisks2_shutdown();
g_hash_table_destroy(memlabels);
g_module_close(cups);
}
Oops, something went wrong.

0 comments on commit 1eb28cd

Please sign in to comment.