Print this page
8485 Remove set but unused variables in usr/src/cmd
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/hal/addons/storage/addon-storage.c
+++ new/usr/src/cmd/hal/addons/storage/addon-storage.c
1 1 /***************************************************************************
2 2 *
3 3 * addon-storage.c : watch removable media state changes
4 4 *
5 + * Copyright 2017 Gary Mills
5 6 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
6 7 * Use is subject to license terms.
7 8 *
8 9 * Licensed under the Academic Free License version 2.1
9 10 *
10 11 **************************************************************************/
11 12
12 13 #ifdef HAVE_CONFIG_H
13 14 # include <config.h>
14 15 #endif
15 16
16 17 #include <errno.h>
17 18 #include <string.h>
18 19 #include <strings.h>
19 20 #include <stdlib.h>
20 21 #include <stdio.h>
21 22 #include <sys/ioctl.h>
22 23 #include <sys/types.h>
23 24 #include <sys/stat.h>
24 25 #include <sys/types.h>
25 26 #include <sys/wait.h>
26 27 #include <fcntl.h>
27 28 #include <unistd.h>
28 29 #include <sys/mnttab.h>
29 30 #include <sys/dkio.h>
30 31 #include <priv.h>
31 32 #include <libsysevent.h>
32 33 #include <sys/sysevent/dev.h>
33 34
34 35 #include <libhal.h>
35 36
36 37 #include "../../hald/logger.h"
37 38
38 39 #define SLEEP_PERIOD 5
39 40
40 41 static char *udi;
41 42 static char *devfs_path;
42 43 LibHalContext *ctx = NULL;
43 44 static sysevent_handle_t *shp = NULL;
44 45
45 46 static void sysevent_dev_handler(sysevent_t *);
46 47
47 48 static void
48 49 my_dbus_error_free(DBusError *error)
49 50 {
50 51 if (dbus_error_is_set(error)) {
51 52 dbus_error_free(error);
52 53 }
53 54 }
54 55
55 56 static void
56 57 sysevent_init ()
57 58 {
58 59 const char *subcl[1];
59 60
60 61 shp = sysevent_bind_handle (sysevent_dev_handler);
61 62 if (shp == NULL) {
62 63 HAL_DEBUG (("sysevent_bind_handle failed %d", errno));
63 64 return;
64 65 }
65 66
66 67 subcl[0] = ESC_DEV_EJECT_REQUEST;
67 68 if (sysevent_subscribe_event (shp, EC_DEV_STATUS, subcl, 1) != 0) {
68 69 HAL_INFO (("subscribe(dev_status) failed %d", errno));
69 70 sysevent_unbind_handle (shp);
70 71 return;
71 72 }
72 73 }
73 74
74 75 static void
75 76 sysevent_fini ()
76 77 {
77 78 if (shp != NULL) {
78 79 sysevent_unbind_handle (shp);
79 80 shp = NULL;
80 81 }
81 82 }
82 83
83 84 static void
84 85 sysevent_dev_handler (sysevent_t *ev)
85 86 {
86 87 char *class;
87 88 char *subclass;
88 89 nvlist_t *attr_list;
89 90 char *phys_path, *path;
90 91 char *p;
91 92 int len;
92 93 DBusError error;
93 94
94 95 if ((class = sysevent_get_class_name (ev)) == NULL)
95 96 return;
96 97
97 98 if ((subclass = sysevent_get_subclass_name (ev)) == NULL)
98 99 return;
99 100
100 101 if ((strcmp (class, EC_DEV_STATUS) != 0) ||
101 102 (strcmp (subclass, ESC_DEV_EJECT_REQUEST) != 0))
102 103 return;
103 104
104 105 if (sysevent_get_attr_list (ev, &attr_list) != 0)
105 106 return;
106 107
107 108 if (nvlist_lookup_string (attr_list, DEV_PHYS_PATH, &phys_path) != 0) {
108 109 goto out;
109 110 }
110 111
111 112 /* see if event belongs to our LUN (ignore slice and "/devices" ) */
112 113 if (strncmp (phys_path, "/devices", sizeof ("/devices") - 1) == 0)
113 114 path = phys_path + sizeof ("/devices") - 1;
114 115 else
115 116 path = phys_path;
116 117
117 118 if ((p = strrchr (path, ':')) == NULL)
118 119 goto out;
119 120 len = (uintptr_t)p - (uintptr_t)path;
120 121 if (strncmp (path, devfs_path, len) != 0)
121 122 goto out;
122 123
123 124 HAL_DEBUG (("sysevent_dev_handler %s %s", subclass, phys_path));
124 125
125 126 /* we got it, tell the world */
126 127 dbus_error_init (&error);
127 128 libhal_device_emit_condition (ctx, udi, "EjectPressed", "", &error);
128 129 dbus_error_free (&error);
129 130
130 131 out:
131 132 nvlist_free(attr_list);
132 133 }
133 134
134 135 static void
135 136 force_unmount (LibHalContext *ctx, const char *udi)
136 137 {
137 138 DBusError error;
138 139 DBusMessage *msg = NULL;
139 140 DBusMessage *reply = NULL;
140 141 char **options = NULL;
141 142 unsigned int num_options = 0;
142 143 DBusConnection *dbus_connection;
143 144 char *device_file;
144 145
145 146 dbus_error_init (&error);
146 147
147 148 dbus_connection = libhal_ctx_get_dbus_connection (ctx);
148 149
149 150 msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
150 151 "org.freedesktop.Hal.Device.Volume",
151 152 "Unmount");
152 153 if (msg == NULL) {
153 154 HAL_DEBUG (("Could not create dbus message for %s", udi));
154 155 goto out;
155 156 }
156 157
157 158
158 159 options = calloc (1, sizeof (char *));
159 160 if (options == NULL) {
160 161 HAL_DEBUG (("Could not allocate options array"));
161 162 goto out;
162 163 }
163 164
164 165 device_file = libhal_device_get_property_string (ctx, udi, "block.device", &error);
165 166 if (device_file != NULL) {
166 167 libhal_free_string (device_file);
167 168 }
168 169 dbus_error_free (&error);
169 170
170 171 if (!dbus_message_append_args (msg,
171 172 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
172 173 DBUS_TYPE_INVALID)) {
173 174 HAL_DEBUG (("Could not append args to dbus message for %s", udi));
174 175 goto out;
175 176 }
176 177
177 178 if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error))) {
178 179 HAL_DEBUG (("Unmount failed for %s: %s : %s\n", udi, error.name, error.message));
179 180 goto out;
180 181 }
181 182
182 183 if (dbus_error_is_set (&error)) {
183 184 HAL_DEBUG (("Unmount failed for %s\n%s : %s\n", udi, error.name, error.message));
184 185 goto out;
185 186 }
186 187
187 188 HAL_DEBUG (("Succesfully unmounted udi '%s'", udi));
188 189
189 190 out:
190 191 dbus_error_free (&error);
191 192 if (options != NULL)
192 193 free (options);
193 194 if (msg != NULL)
194 195 dbus_message_unref (msg);
195 196 if (reply != NULL)
196 197 dbus_message_unref (reply);
197 198 }
198 199
199 200 static void
200 201 unmount_childs (LibHalContext *ctx, const char *udi)
201 202 {
202 203 DBusError error;
203 204 int num_volumes;
204 205 char **volumes;
205 206
206 207 dbus_error_init (&error);
207 208
208 209 /* need to force unmount all partitions */
209 210 if ((volumes = libhal_manager_find_device_string_match (
210 211 ctx, "block.storage_device", udi, &num_volumes, &error)) != NULL) {
211 212 dbus_error_free (&error);
212 213 int i;
213 214
214 215 for (i = 0; i < num_volumes; i++) {
215 216 char *vol_udi;
216 217
217 218 vol_udi = volumes[i];
218 219 if (libhal_device_get_property_bool (ctx, vol_udi, "block.is_volume", &error)) {
219 220 dbus_error_free (&error);
220 221 if (libhal_device_get_property_bool (ctx, vol_udi, "volume.is_mounted", &error)) {
221 222 dbus_error_free (&error);
222 223 HAL_DEBUG (("Forcing unmount of child '%s'", vol_udi));
223 224 force_unmount (ctx, vol_udi);
224 225 }
225 226 }
226 227 }
227 228 libhal_free_string_array (volumes);
228 229 }
229 230 my_dbus_error_free (&error);
230 231 }
231 232
232 233 /** Check if a filesystem on a special device file is mounted
233 234 *
234 235 * @param device_file Special device file, e.g. /dev/cdrom
235 236 * @return TRUE iff there is a filesystem system mounted
236 237 * on the special device file
237 238 */
238 239 static dbus_bool_t
239 240 is_mounted (const char *device_file)
240 241 {
241 242 FILE *f;
242 243 dbus_bool_t rc = FALSE;
243 244 struct mnttab mp;
244 245 struct mnttab mpref;
245 246
246 247 if ((f = fopen ("/etc/mnttab", "r")) == NULL)
247 248 return rc;
248 249
249 250 bzero(&mp, sizeof (mp));
250 251 bzero(&mpref, sizeof (mpref));
251 252 mpref.mnt_special = (char *)device_file;
252 253 if (getmntany(f, &mp, &mpref) == 0) {
253 254 rc = TRUE;
254 255 }
255 256
256 257 fclose (f);
257 258 return rc;
258 259 }
259 260
260 261 void
261 262 close_device (int *fd)
262 263 {
263 264 if (*fd > 0) {
264 265 close (*fd);
265 266 *fd = -1;
266 267 }
267 268 }
268 269
269 270 void
270 271 drop_privileges ()
271 272 {
272 273 priv_set_t *pPrivSet = NULL;
273 274 priv_set_t *lPrivSet = NULL;
274 275
275 276 /*
276 277 * Start with the 'basic' privilege set and then remove any
277 278 * of the 'basic' privileges that will not be needed.
278 279 */
279 280 if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
280 281 return;
281 282 }
282 283
283 284 /* Clear privileges we will not need from the 'basic' set */
284 285 (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
285 286 (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
286 287 (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
287 288
288 289 /* to open logindevperm'd devices */
289 290 (void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
290 291
291 292 /* to receive sysevents */
292 293 (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG);
293 294
294 295 /* Set the permitted privilege set. */
295 296 if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
296 297 return;
297 298 }
298 299
299 300 /* Clear the limit set. */
300 301 if ((lPrivSet = priv_allocset()) == NULL) {
301 302 return;
302 303 }
303 304
304 305 priv_emptyset(lPrivSet);
305 306
306 307 if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
307 308 return;
308 309 }
309 310
310 311 priv_freeset(lPrivSet);
↓ open down ↓ |
296 lines elided |
↑ open up ↑ |
311 312 }
312 313
313 314 int
314 315 main (int argc, char *argv[])
315 316 {
316 317 char *device_file, *raw_device_file;
317 318 DBusError error;
318 319 char *bus;
319 320 char *drive_type;
320 321 int state, last_state;
321 - char *support_media_changed_str;
322 - int support_media_changed;
323 322 int fd = -1;
324 323
325 324 if ((udi = getenv ("UDI")) == NULL)
326 325 goto out;
327 326 if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
328 327 goto out;
329 328 if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
330 329 goto out;
331 330 if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
332 331 goto out;
333 332 if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
334 333 goto out;
335 334 if ((devfs_path = getenv ("HAL_PROP_SOLARIS_DEVFS_PATH")) == NULL)
336 335 goto out;
337 336
338 337 drop_privileges ();
339 338
340 339 setup_logger ();
341 340
342 341 sysevent_init ();
343 342
344 - support_media_changed_str = getenv ("HAL_PROP_STORAGE_CDROM_SUPPORT_MEDIA_CHANGED");
345 - if (support_media_changed_str != NULL && strcmp (support_media_changed_str, "true") == 0)
346 - support_media_changed = TRUE;
347 - else
348 - support_media_changed = FALSE;
349 -
350 343 dbus_error_init (&error);
351 344
352 345 if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
353 346 goto out;
354 347 }
355 348 my_dbus_error_free (&error);
356 349
357 350 if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
358 351 goto out;
359 352 }
360 353 my_dbus_error_free (&error);
361 354
362 355 printf ("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)\n", device_file, bus, drive_type, udi);
363 356
364 357 last_state = state = DKIO_NONE;
365 358
366 359 /* Linux version of this addon attempts to re-open the device O_EXCL
367 360 * every 2 seconds, trying to figure out if some other app,
368 361 * like a cd burner, is using the device. Aside from questionable
369 362 * value of this (apps should use HAL's locked property or/and
370 363 * Solaris in_use facility), but also frequent opens/closes
371 364 * keeps media constantly spun up. All this needs more thought.
372 365 */
373 366 for (;;) {
374 367 if (is_mounted (device_file)) {
375 368 close_device (&fd);
376 369 sleep (SLEEP_PERIOD);
377 370 } else if ((fd < 0) && ((fd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0)) {
378 371 HAL_DEBUG (("open failed for %s: %s", raw_device_file, strerror (errno)));
379 372 sleep (SLEEP_PERIOD);
380 373 } else {
381 374 /* Check if a disc is in the drive */
382 375 /* XXX initial call always returns inserted
383 376 * causing unnecessary rescan - optimize?
384 377 */
385 378 if (ioctl (fd, DKIOCSTATE, &state) == 0) {
386 379 if (state == last_state) {
387 380 HAL_DEBUG (("state has not changed %d %s", state, device_file));
388 381 continue;
389 382 } else {
390 383 HAL_DEBUG (("new state %d %s", state, device_file));
391 384 }
392 385
393 386 switch (state) {
394 387 case DKIO_EJECTED:
395 388 HAL_DEBUG (("Media removal detected on %s", device_file));
396 389 last_state = state;
397 390
398 391 libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
399 392 my_dbus_error_free (&error);
400 393
401 394 /* attempt to unmount all childs */
402 395 unmount_childs (ctx, udi);
403 396
404 397 /* could have a fs on the main block device; do a rescan to remove it */
405 398 libhal_device_rescan (ctx, udi, &error);
406 399 my_dbus_error_free (&error);
407 400 break;
408 401
409 402 case DKIO_INSERTED:
410 403 HAL_DEBUG (("Media insertion detected on %s", device_file));
411 404 last_state = state;
412 405
413 406 libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
414 407 my_dbus_error_free (&error);
415 408
416 409 /* could have a fs on the main block device; do a rescan to add it */
417 410 libhal_device_rescan (ctx, udi, &error);
418 411 my_dbus_error_free (&error);
419 412 break;
420 413
421 414 case DKIO_DEV_GONE:
422 415 HAL_DEBUG (("Device gone detected on %s", device_file));
423 416 last_state = state;
424 417
425 418 unmount_childs (ctx, udi);
426 419 close_device (&fd);
427 420 goto out;
428 421
429 422 case DKIO_NONE:
430 423 default:
431 424 break;
432 425 }
433 426 } else {
434 427 HAL_DEBUG (("DKIOCSTATE failed: %s\n", strerror(errno)));
435 428 sleep (SLEEP_PERIOD);
436 429 }
437 430 }
438 431 }
439 432
440 433 out:
441 434 sysevent_fini ();
442 435 if (ctx != NULL) {
443 436 my_dbus_error_free (&error);
444 437 libhal_ctx_shutdown (ctx, &error);
445 438 libhal_ctx_free (ctx);
446 439 }
447 440
448 441 return 0;
449 442 }
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX