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