xref: /titanic_50/usr/src/cmd/hal/addons/network-devices/cache.c (revision 4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3)
1*4e9cfc9aSjacobs /*
2*4e9cfc9aSjacobs  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3*4e9cfc9aSjacobs  * Use is subject to license terms.
4*4e9cfc9aSjacobs  *
5*4e9cfc9aSjacobs  * Licensed under the Academic Free License version 2.1
6*4e9cfc9aSjacobs  */
7*4e9cfc9aSjacobs 
8*4e9cfc9aSjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
9*4e9cfc9aSjacobs 
10*4e9cfc9aSjacobs #include <stdio.h>
11*4e9cfc9aSjacobs #include <stdlib.h>
12*4e9cfc9aSjacobs #include <unistd.h>
13*4e9cfc9aSjacobs #include <string.h>
14*4e9cfc9aSjacobs 
15*4e9cfc9aSjacobs #include <libhal.h>
16*4e9cfc9aSjacobs #include <logger.h>
17*4e9cfc9aSjacobs 
18*4e9cfc9aSjacobs #include <glib.h>
19*4e9cfc9aSjacobs 
20*4e9cfc9aSjacobs #include "network-discovery.h"
21*4e9cfc9aSjacobs 
22*4e9cfc9aSjacobs /*
23*4e9cfc9aSjacobs  * The interfaces in this file comprise a means of keeping track of devices
24*4e9cfc9aSjacobs  * that we have already seen and those that have gone missing.  This allows
25*4e9cfc9aSjacobs  * us to quickly determine if we need to probe the device and quickly search
26*4e9cfc9aSjacobs  * for devices that are no longer available.
27*4e9cfc9aSjacobs  */
28*4e9cfc9aSjacobs 
29*4e9cfc9aSjacobs typedef struct {
30*4e9cfc9aSjacobs 	LibHalContext *ctx;
31*4e9cfc9aSjacobs 	time_t timestamp;
32*4e9cfc9aSjacobs } removal_args_t;
33*4e9cfc9aSjacobs 
34*4e9cfc9aSjacobs static GHashTable *seen = NULL;
35*4e9cfc9aSjacobs 
36*4e9cfc9aSjacobs static gboolean
device_remove_if_stale(gpointer key,gpointer value,gpointer user_data)37*4e9cfc9aSjacobs device_remove_if_stale(gpointer key, gpointer value, gpointer user_data)
38*4e9cfc9aSjacobs {
39*4e9cfc9aSjacobs 	gboolean result = FALSE;
40*4e9cfc9aSjacobs 	removal_args_t *args = user_data;
41*4e9cfc9aSjacobs 	char *name = key;
42*4e9cfc9aSjacobs 	time_t *val = value;
43*4e9cfc9aSjacobs 
44*4e9cfc9aSjacobs 	HAL_DEBUG(("test stale: %s (%d > %d)", name, args->timestamp, *val));
45*4e9cfc9aSjacobs 	if (args->timestamp > *val) {
46*4e9cfc9aSjacobs 		DBusError error;
47*4e9cfc9aSjacobs 		char **udi = NULL;
48*4e9cfc9aSjacobs 		int num = 0;
49*4e9cfc9aSjacobs 
50*4e9cfc9aSjacobs 		dbus_error_init(&error);
51*4e9cfc9aSjacobs 		udi = libhal_manager_find_device_string_match(args->ctx,
52*4e9cfc9aSjacobs 					"network_device.address", name,
53*4e9cfc9aSjacobs 					&num, &error);
54*4e9cfc9aSjacobs 
55*4e9cfc9aSjacobs 		if (udi != NULL) {
56*4e9cfc9aSjacobs 			int i;
57*4e9cfc9aSjacobs 
58*4e9cfc9aSjacobs 			for (i = 0; i < num; i++) {
59*4e9cfc9aSjacobs 				libhal_remove_device(args->ctx, udi[i], &error);
60*4e9cfc9aSjacobs 				HAL_DEBUG(("remove: %s (%s)", name, udi[i]));
61*4e9cfc9aSjacobs 			}
62*4e9cfc9aSjacobs 			libhal_free_string_array(udi);
63*4e9cfc9aSjacobs 			result = TRUE;
64*4e9cfc9aSjacobs 		}
65*4e9cfc9aSjacobs 		if (dbus_error_is_set(&error))
66*4e9cfc9aSjacobs 			dbus_error_free(&error);
67*4e9cfc9aSjacobs 	}
68*4e9cfc9aSjacobs 
69*4e9cfc9aSjacobs 	return (result);
70*4e9cfc9aSjacobs }
71*4e9cfc9aSjacobs 
72*4e9cfc9aSjacobs void
scan_for_stale_devices(LibHalContext * ctx,time_t timestamp)73*4e9cfc9aSjacobs scan_for_stale_devices(LibHalContext *ctx, time_t timestamp)
74*4e9cfc9aSjacobs {
75*4e9cfc9aSjacobs 	if (seen != NULL) {
76*4e9cfc9aSjacobs 		removal_args_t args[1];
77*4e9cfc9aSjacobs 
78*4e9cfc9aSjacobs 		args->ctx = ctx;
79*4e9cfc9aSjacobs 		args->timestamp = timestamp;
80*4e9cfc9aSjacobs 
81*4e9cfc9aSjacobs 		g_hash_table_foreach_remove(seen, device_remove_if_stale, args);
82*4e9cfc9aSjacobs 	}
83*4e9cfc9aSjacobs }
84*4e9cfc9aSjacobs 
85*4e9cfc9aSjacobs gboolean
device_seen(char * name)86*4e9cfc9aSjacobs device_seen(char *name)
87*4e9cfc9aSjacobs {
88*4e9cfc9aSjacobs 	gboolean result;
89*4e9cfc9aSjacobs 	char *key;
90*4e9cfc9aSjacobs 	time_t *val;
91*4e9cfc9aSjacobs 
92*4e9cfc9aSjacobs 	if (seen == NULL)
93*4e9cfc9aSjacobs 		seen = g_hash_table_new_full(g_str_hash, g_str_equal,
94*4e9cfc9aSjacobs 						free, free);
95*4e9cfc9aSjacobs 
96*4e9cfc9aSjacobs 	result = g_hash_table_lookup_extended(seen, name,
97*4e9cfc9aSjacobs 				(gpointer)&key, (gpointer)&val);
98*4e9cfc9aSjacobs 
99*4e9cfc9aSjacobs 	if ((result == FALSE) && ((val = calloc(1, sizeof (*val))) != NULL)) {
100*4e9cfc9aSjacobs 		g_hash_table_insert(seen, strdup(name), val);
101*4e9cfc9aSjacobs 	}
102*4e9cfc9aSjacobs 	(void) time(val);
103*4e9cfc9aSjacobs 	HAL_DEBUG(("seen: %s (%d)", name, *val));
104*4e9cfc9aSjacobs 
105*4e9cfc9aSjacobs 	return (result);
106*4e9cfc9aSjacobs }
107