xref: /dflybsd-src/sbin/udevd/udevd_pdev.c (revision 0c8103dd622e5016512e2eedb2ceb865982089a5)
12e7bf158SAlex Hornung /*
22e7bf158SAlex Hornung  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
32e7bf158SAlex Hornung  *
42e7bf158SAlex Hornung  * This code is derived from software contributed to The DragonFly Project
52e7bf158SAlex Hornung  * by Alex Hornung <ahornung@gmail.com>
62e7bf158SAlex Hornung  *
72e7bf158SAlex Hornung  * Redistribution and use in source and binary forms, with or without
82e7bf158SAlex Hornung  * modification, are permitted provided that the following conditions
92e7bf158SAlex Hornung  * are met:
102e7bf158SAlex Hornung  *
112e7bf158SAlex Hornung  * 1. Redistributions of source code must retain the above copyright
122e7bf158SAlex Hornung  *    notice, this list of conditions and the following disclaimer.
132e7bf158SAlex Hornung  * 2. Redistributions in binary form must reproduce the above copyright
142e7bf158SAlex Hornung  *    notice, this list of conditions and the following disclaimer in
152e7bf158SAlex Hornung  *    the documentation and/or other materials provided with the
162e7bf158SAlex Hornung  *    distribution.
172e7bf158SAlex Hornung  * 3. Neither the name of The DragonFly Project nor the names of its
182e7bf158SAlex Hornung  *    contributors may be used to endorse or promote products derived
192e7bf158SAlex Hornung  *    from this software without specific, prior written permission.
202e7bf158SAlex Hornung  *
212e7bf158SAlex Hornung  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
222e7bf158SAlex Hornung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
232e7bf158SAlex Hornung  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
242e7bf158SAlex Hornung  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
252e7bf158SAlex Hornung  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
262e7bf158SAlex Hornung  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
272e7bf158SAlex Hornung  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
282e7bf158SAlex Hornung  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
292e7bf158SAlex Hornung  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
302e7bf158SAlex Hornung  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
312e7bf158SAlex Hornung  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
322e7bf158SAlex Hornung  * SUCH DAMAGE.
332e7bf158SAlex Hornung  */
342e7bf158SAlex Hornung #include <sys/types.h>
352e7bf158SAlex Hornung #include <sys/device.h>
362e7bf158SAlex Hornung #include <sys/wait.h>
372e7bf158SAlex Hornung #include <sys/socket.h>
382e7bf158SAlex Hornung #include <sys/ioctl.h>
392e7bf158SAlex Hornung #include <sys/poll.h>
402e7bf158SAlex Hornung #include <sys/queue.h>
412e7bf158SAlex Hornung #include <sys/un.h>
422e7bf158SAlex Hornung 
432e7bf158SAlex Hornung #include <err.h>
442e7bf158SAlex Hornung #include <errno.h>
452e7bf158SAlex Hornung #include <fcntl.h>
462e7bf158SAlex Hornung #include <libgen.h>
472e7bf158SAlex Hornung #include <regex.h>
482e7bf158SAlex Hornung #include <signal.h>
492e7bf158SAlex Hornung #include <stdarg.h>
502e7bf158SAlex Hornung #include <stdio.h>
512e7bf158SAlex Hornung #include <stdlib.h>
522e7bf158SAlex Hornung #include <string.h>
532e7bf158SAlex Hornung #include <syslog.h>
542e7bf158SAlex Hornung #include <unistd.h>
552e7bf158SAlex Hornung #include <pthread.h>
562e7bf158SAlex Hornung 
572e7bf158SAlex Hornung #include <libprop/proplib.h>
582e7bf158SAlex Hornung #include <sys/udev.h>
592e7bf158SAlex Hornung #include "udevd.h"
602e7bf158SAlex Hornung 
612e7bf158SAlex Hornung static int64_t udev_generation;
622e7bf158SAlex Hornung TAILQ_HEAD(pdev_array_list_head, pdev_array_entry)	pdev_array_list;
632e7bf158SAlex Hornung 
642e7bf158SAlex Hornung void
pdev_array_entry_ref(struct pdev_array_entry * pae)652e7bf158SAlex Hornung pdev_array_entry_ref(struct pdev_array_entry *pae)
662e7bf158SAlex Hornung {
672e7bf158SAlex Hornung 	++pae->refs;
682e7bf158SAlex Hornung }
692e7bf158SAlex Hornung 
702e7bf158SAlex Hornung void
pdev_array_entry_unref(struct pdev_array_entry * pae)712e7bf158SAlex Hornung pdev_array_entry_unref(struct pdev_array_entry *pae)
722e7bf158SAlex Hornung {
732e7bf158SAlex Hornung 	if (--pae->refs == 0) {
742e7bf158SAlex Hornung 		TAILQ_REMOVE(&pdev_array_list, pae, link);
752e7bf158SAlex Hornung 		prop_object_release(pae->pdev_array); /* XXX */
762e7bf158SAlex Hornung 		free(pae);
772e7bf158SAlex Hornung 	}
782e7bf158SAlex Hornung }
792e7bf158SAlex Hornung 
802e7bf158SAlex Hornung void
pdev_array_entry_insert(prop_array_t pa)812e7bf158SAlex Hornung pdev_array_entry_insert(prop_array_t pa)
822e7bf158SAlex Hornung {
832e7bf158SAlex Hornung 	struct pdev_array_entry *pae, *opae = NULL;
842e7bf158SAlex Hornung 
852e7bf158SAlex Hornung 	if (pa == NULL)
862e7bf158SAlex Hornung 		errx(1, "null prop_array in insert_pdev_array");
872e7bf158SAlex Hornung 	pae = malloc(sizeof(struct pdev_array_entry));
882e7bf158SAlex Hornung 	if (pae == NULL)
892e7bf158SAlex Hornung 		errx(1, "insert_pdev_array could not allocate mem");
902e7bf158SAlex Hornung 	memset(pae, 0, sizeof(struct pdev_array_entry));
912e7bf158SAlex Hornung 	pae->pdev_array = pa;
922e7bf158SAlex Hornung 	pae->generation = udev_generation++;
932e7bf158SAlex Hornung 	pae->refs = 1; /* One ref because it's the most recent one */
942e7bf158SAlex Hornung 
952e7bf158SAlex Hornung 	/*
962e7bf158SAlex Hornung 	 * If the TAILQ is not empty, unref the last entry,
972e7bf158SAlex Hornung 	 * as it isn't needed anymore.
982e7bf158SAlex Hornung 	 */
992e7bf158SAlex Hornung 	if (!TAILQ_EMPTY(&pdev_array_list))
1002e7bf158SAlex Hornung 		opae = TAILQ_LAST(&pdev_array_list, pdev_array_list_head);
1012e7bf158SAlex Hornung 
1022e7bf158SAlex Hornung 	TAILQ_INSERT_TAIL(&pdev_array_list, pae, link);
1032e7bf158SAlex Hornung 
1042e7bf158SAlex Hornung 	if (opae != NULL)
1052e7bf158SAlex Hornung 		pdev_array_entry_unref(opae);
1062e7bf158SAlex Hornung }
1072e7bf158SAlex Hornung 
108*9ff03f9eSAlex Hornung void
pdev_array_clean(void)109*9ff03f9eSAlex Hornung pdev_array_clean(void)
110*9ff03f9eSAlex Hornung {
111*9ff03f9eSAlex Hornung 	struct pdev_array_entry *pae;
112*9ff03f9eSAlex Hornung 
113*9ff03f9eSAlex Hornung 	while ((pae = TAILQ_LAST(&pdev_array_list, pdev_array_list_head)) != NULL) {
114*9ff03f9eSAlex Hornung 		TAILQ_REMOVE(&pdev_array_list, pae, link);
115*9ff03f9eSAlex Hornung 		prop_object_release(pae->pdev_array);
116*9ff03f9eSAlex Hornung 		free(pae);
117*9ff03f9eSAlex Hornung 	}
118*9ff03f9eSAlex Hornung }
119*9ff03f9eSAlex Hornung 
1202e7bf158SAlex Hornung struct pdev_array_entry *
pdev_array_entry_get(int64_t generation)1212e7bf158SAlex Hornung pdev_array_entry_get(int64_t generation)
1222e7bf158SAlex Hornung {
1232e7bf158SAlex Hornung 	struct pdev_array_entry *pae;
1242e7bf158SAlex Hornung 	int found = 0;
1252e7bf158SAlex Hornung 
1262e7bf158SAlex Hornung 	TAILQ_FOREACH(pae, &pdev_array_list, link) {
1272e7bf158SAlex Hornung 		if (pae->generation == generation) {
1282e7bf158SAlex Hornung 			found = 1;
1292e7bf158SAlex Hornung 			break;
1302e7bf158SAlex Hornung 		}
1312e7bf158SAlex Hornung 	}
1322e7bf158SAlex Hornung 
1332e7bf158SAlex Hornung 	if (!found)
1342e7bf158SAlex Hornung 		return NULL;
1352e7bf158SAlex Hornung 
1362e7bf158SAlex Hornung 	pdev_array_entry_ref(pae);
1372e7bf158SAlex Hornung 	return pae;
1382e7bf158SAlex Hornung }
1392e7bf158SAlex Hornung 
1402e7bf158SAlex Hornung struct pdev_array_entry *
pdev_array_entry_get_last(void)1412e7bf158SAlex Hornung pdev_array_entry_get_last(void)
1422e7bf158SAlex Hornung {
1432e7bf158SAlex Hornung 	struct pdev_array_entry *pae;
1442e7bf158SAlex Hornung 
1452e7bf158SAlex Hornung 	pae = TAILQ_LAST(&pdev_array_list, pdev_array_list_head);
1462e7bf158SAlex Hornung 
1472e7bf158SAlex Hornung 	pdev_array_entry_ref(pae);
1482e7bf158SAlex Hornung 	return pae;
1492e7bf158SAlex Hornung }
150