4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25 */
26
27 /*
28 * restarter.c - service manipulation
29 *
30 * This component manages services whose restarter is svc.startd, the standard
31 * restarter. It translates restarter protocol events from the graph engine
32 * into actions on processes, as a delegated restarter would do.
33 *
34 * The master restarter manages a number of always-running threads:
35 * - restarter event thread: events from the graph engine
36 * - timeout thread: thread to fire queued timeouts
37 * - contract thread: thread to handle contract events
38 * - wait thread: thread to handle wait-based services
39 *
40 * The other threads are created as-needed:
41 * - per-instance method threads
42 * - per-instance event processing threads
43 *
44 * The interaction of all threads must result in the following conditions
977
978 case EACCES:
979 default:
980 bad_error("libscf_snapshots_poststart", r);
981 }
982 }
983
984 MUTEX_UNLOCK(&inst->ri_lock);
985 }
986
987 MUTEX_UNLOCK(&instance_list.ril_lock);
988 }
989
990 /* ARGSUSED */
991 void *
992 restarter_post_fsminimal_thread(void *unused)
993 {
994 scf_handle_t *h;
995 int r;
996
997 h = libscf_handle_create_bound_loop();
998
999 for (;;) {
1000 r = libscf_create_self(h);
1001 if (r == 0)
1002 break;
1003
1004 assert(r == ECONNABORTED);
1005 libscf_handle_rebind(h);
1006 }
1007
1008 restarter_take_pending_snapshots(h);
1009
1010 (void) scf_handle_unbind(h);
1011 scf_handle_destroy(h);
1012
1013 return (NULL);
1014 }
1015
1016 /*
1754 "INVALID_DEPENDENCY", "ADMIN_DISABLE", "STOP_RESET"
1755 };
1756
1757 /*
1758 * void *restarter_process_events()
1759 *
1760 * Called in a separate thread to process the events on an instance's
1761 * queue. Empties the queue completely, and tries to keep the thread
1762 * around for a little while after the queue is empty to save on
1763 * startup costs.
1764 */
1765 static void *
1766 restarter_process_events(void *arg)
1767 {
1768 scf_handle_t *h;
1769 restarter_instance_qentry_t *event;
1770 restarter_inst_t *rip;
1771 char *fmri = (char *)arg;
1772 struct timespec to;
1773
1774 assert(fmri != NULL);
1775
1776 h = libscf_handle_create_bound_loop();
1777
1778 /* grab the queue lock */
1779 rip = inst_lookup_queue(fmri);
1780 if (rip == NULL)
1781 goto out;
1782
1783 again:
1784
1785 while ((event = uu_list_first(rip->ri_queue)) != NULL) {
1786 restarter_inst_t *inst;
1787
1788 /* drop the queue lock */
1789 MUTEX_UNLOCK(&rip->ri_queue_lock);
1790
1791 /*
1792 * Grab the inst lock -- this waits until any outstanding
1793 * method finishes running.
1922 */
1923 to.tv_sec = 3;
1924 to.tv_nsec = 0;
1925 (void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1926 &rip->ri_queue_lock, &to);
1927
1928 if (uu_list_first(rip->ri_queue) != NULL)
1929 goto again;
1930
1931 rip->ri_queue_thread = 0;
1932 MUTEX_UNLOCK(&rip->ri_queue_lock);
1933
1934 out:
1935 (void) scf_handle_unbind(h);
1936 scf_handle_destroy(h);
1937 free(fmri);
1938 return (NULL);
1939 }
1940
1941 static int
1942 is_admin_event(restarter_event_type_t t) {
1943
1944 switch (t) {
1945 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1946 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1947 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1948 case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1949 case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1950 case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1951 return (1);
1952 default:
1953 return (0);
1954 }
1955 }
1956
1957 static void
1958 restarter_queue_event(restarter_inst_t *ri, restarter_protocol_event_t *e)
1959 {
1960 restarter_instance_qentry_t *qe;
1961 int r;
1962
1963 assert(MUTEX_HELD(&ri->ri_queue_lock));
1968 qe->riq_reason = e->rpe_reason;
1969
1970 uu_list_node_init(qe, &qe->riq_link, restarter_queue_pool);
1971 r = uu_list_insert_before(ri->ri_queue, NULL, qe);
1972 assert(r == 0);
1973 }
1974
1975 /*
1976 * void *restarter_event_thread()
1977 *
1978 * Handle incoming graph events by placing them on a per-instance
1979 * queue. We can't lock the main part of the instance structure, so
1980 * just modify the seprarately locked event queue portion.
1981 */
1982 /*ARGSUSED*/
1983 static void *
1984 restarter_event_thread(void *unused)
1985 {
1986 scf_handle_t *h;
1987
1988 /*
1989 * This is a new thread, and thus, gets its own handle
1990 * to the repository.
1991 */
1992 h = libscf_handle_create_bound_loop();
1993
1994 MUTEX_LOCK(&ru->restarter_update_lock);
1995
1996 /*CONSTCOND*/
1997 while (1) {
1998 restarter_protocol_event_t *e;
1999
2000 while (ru->restarter_update_wakeup == 0)
2001 (void) pthread_cond_wait(&ru->restarter_update_cv,
2002 &ru->restarter_update_lock);
2003
2004 ru->restarter_update_wakeup = 0;
2005
2006 while ((e = restarter_event_dequeue()) != NULL) {
2007 restarter_inst_t *rip;
2179 break;
2180 case CT_PR_EV_HWERR:
2181 (void) stop_instance(h, inst, RSTOP_HWERR);
2182 break;
2183 }
2184 }
2185 }
2186
2187 /*
2188 * void *restarter_contract_event_thread(void *)
2189 * Listens to the process contract bundle for critical events, taking action
2190 * on events from contracts we know we are responsible for.
2191 */
2192 /*ARGSUSED*/
2193 static void *
2194 restarter_contracts_event_thread(void *unused)
2195 {
2196 int fd, err;
2197 scf_handle_t *local_handle;
2198
2199 /*
2200 * Await graph load completion. That is, stop here, until we've scanned
2201 * the repository for contract - instance associations.
2202 */
2203 MUTEX_LOCK(&st->st_load_lock);
2204 while (!(st->st_load_complete && st->st_load_instances == 0))
2205 (void) pthread_cond_wait(&st->st_load_cv, &st->st_load_lock);
2206 MUTEX_UNLOCK(&st->st_load_lock);
2207
2208 /*
2209 * This is a new thread, and thus, gets its own handle
2210 * to the repository.
2211 */
2212 if ((local_handle = libscf_handle_create_bound(SCF_VERSION)) == NULL)
2213 uu_die("Unable to bind a new repository handle: %s\n",
2214 scf_strerror(scf_error()));
2215
2216 fd = open64(CTFS_ROOT "/process/pbundle", O_RDONLY);
2217 if (fd == -1)
2218 uu_die("process bundle open failed");
2528
2529 return (ret);
2530 }
2531
2532 /*
2533 * void *restarter_timeouts_event_thread(void *)
2534 * Responsible for monitoring the method timeouts. This thread must
2535 * be started before any methods are called.
2536 */
2537 /*ARGSUSED*/
2538 static void *
2539 restarter_timeouts_event_thread(void *unused)
2540 {
2541 /*
2542 * Timeouts are entered on a priority queue, which is processed by
2543 * this thread. As timeouts are specified in seconds, we'll do
2544 * the necessary processing every second, as long as the queue
2545 * is not empty.
2546 */
2547
2548 /*CONSTCOND*/
2549 while (1) {
2550 /*
2551 * As long as the timeout list isn't empty, process it
2552 * every second.
2553 */
2554 if (timeout_now() == 0) {
2555 (void) sleep(1);
2556 continue;
2557 }
2558
2559 /* The list is empty, wait until we have more timeouts. */
2560 MUTEX_LOCK(&tu->tu_lock);
2561
2562 while (tu->tu_wakeup == 0)
2563 (void) pthread_cond_wait(&tu->tu_cv, &tu->tu_lock);
2564
2565 tu->tu_wakeup = 0;
2566 MUTEX_UNLOCK(&tu->tu_lock);
2567 }
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018 Joyent, Inc.
25 */
26
27 /*
28 * restarter.c - service manipulation
29 *
30 * This component manages services whose restarter is svc.startd, the standard
31 * restarter. It translates restarter protocol events from the graph engine
32 * into actions on processes, as a delegated restarter would do.
33 *
34 * The master restarter manages a number of always-running threads:
35 * - restarter event thread: events from the graph engine
36 * - timeout thread: thread to fire queued timeouts
37 * - contract thread: thread to handle contract events
38 * - wait thread: thread to handle wait-based services
39 *
40 * The other threads are created as-needed:
41 * - per-instance method threads
42 * - per-instance event processing threads
43 *
44 * The interaction of all threads must result in the following conditions
977
978 case EACCES:
979 default:
980 bad_error("libscf_snapshots_poststart", r);
981 }
982 }
983
984 MUTEX_UNLOCK(&inst->ri_lock);
985 }
986
987 MUTEX_UNLOCK(&instance_list.ril_lock);
988 }
989
990 /* ARGSUSED */
991 void *
992 restarter_post_fsminimal_thread(void *unused)
993 {
994 scf_handle_t *h;
995 int r;
996
997 (void) pthread_setname_np(pthread_self(), "restarter_post_fsmin");
998
999 h = libscf_handle_create_bound_loop();
1000
1001 for (;;) {
1002 r = libscf_create_self(h);
1003 if (r == 0)
1004 break;
1005
1006 assert(r == ECONNABORTED);
1007 libscf_handle_rebind(h);
1008 }
1009
1010 restarter_take_pending_snapshots(h);
1011
1012 (void) scf_handle_unbind(h);
1013 scf_handle_destroy(h);
1014
1015 return (NULL);
1016 }
1017
1018 /*
1756 "INVALID_DEPENDENCY", "ADMIN_DISABLE", "STOP_RESET"
1757 };
1758
1759 /*
1760 * void *restarter_process_events()
1761 *
1762 * Called in a separate thread to process the events on an instance's
1763 * queue. Empties the queue completely, and tries to keep the thread
1764 * around for a little while after the queue is empty to save on
1765 * startup costs.
1766 */
1767 static void *
1768 restarter_process_events(void *arg)
1769 {
1770 scf_handle_t *h;
1771 restarter_instance_qentry_t *event;
1772 restarter_inst_t *rip;
1773 char *fmri = (char *)arg;
1774 struct timespec to;
1775
1776 (void) pthread_setname_np(pthread_self(), "restarter_process_events");
1777
1778 assert(fmri != NULL);
1779
1780 h = libscf_handle_create_bound_loop();
1781
1782 /* grab the queue lock */
1783 rip = inst_lookup_queue(fmri);
1784 if (rip == NULL)
1785 goto out;
1786
1787 again:
1788
1789 while ((event = uu_list_first(rip->ri_queue)) != NULL) {
1790 restarter_inst_t *inst;
1791
1792 /* drop the queue lock */
1793 MUTEX_UNLOCK(&rip->ri_queue_lock);
1794
1795 /*
1796 * Grab the inst lock -- this waits until any outstanding
1797 * method finishes running.
1926 */
1927 to.tv_sec = 3;
1928 to.tv_nsec = 0;
1929 (void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1930 &rip->ri_queue_lock, &to);
1931
1932 if (uu_list_first(rip->ri_queue) != NULL)
1933 goto again;
1934
1935 rip->ri_queue_thread = 0;
1936 MUTEX_UNLOCK(&rip->ri_queue_lock);
1937
1938 out:
1939 (void) scf_handle_unbind(h);
1940 scf_handle_destroy(h);
1941 free(fmri);
1942 return (NULL);
1943 }
1944
1945 static int
1946 is_admin_event(restarter_event_type_t t)
1947 {
1948 switch (t) {
1949 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1950 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1951 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1952 case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1953 case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1954 case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1955 return (1);
1956 default:
1957 return (0);
1958 }
1959 }
1960
1961 static void
1962 restarter_queue_event(restarter_inst_t *ri, restarter_protocol_event_t *e)
1963 {
1964 restarter_instance_qentry_t *qe;
1965 int r;
1966
1967 assert(MUTEX_HELD(&ri->ri_queue_lock));
1972 qe->riq_reason = e->rpe_reason;
1973
1974 uu_list_node_init(qe, &qe->riq_link, restarter_queue_pool);
1975 r = uu_list_insert_before(ri->ri_queue, NULL, qe);
1976 assert(r == 0);
1977 }
1978
1979 /*
1980 * void *restarter_event_thread()
1981 *
1982 * Handle incoming graph events by placing them on a per-instance
1983 * queue. We can't lock the main part of the instance structure, so
1984 * just modify the seprarately locked event queue portion.
1985 */
1986 /*ARGSUSED*/
1987 static void *
1988 restarter_event_thread(void *unused)
1989 {
1990 scf_handle_t *h;
1991
1992 (void) pthread_setname_np(pthread_self(), "restarter_event");
1993
1994 /*
1995 * This is a new thread, and thus, gets its own handle
1996 * to the repository.
1997 */
1998 h = libscf_handle_create_bound_loop();
1999
2000 MUTEX_LOCK(&ru->restarter_update_lock);
2001
2002 /*CONSTCOND*/
2003 while (1) {
2004 restarter_protocol_event_t *e;
2005
2006 while (ru->restarter_update_wakeup == 0)
2007 (void) pthread_cond_wait(&ru->restarter_update_cv,
2008 &ru->restarter_update_lock);
2009
2010 ru->restarter_update_wakeup = 0;
2011
2012 while ((e = restarter_event_dequeue()) != NULL) {
2013 restarter_inst_t *rip;
2185 break;
2186 case CT_PR_EV_HWERR:
2187 (void) stop_instance(h, inst, RSTOP_HWERR);
2188 break;
2189 }
2190 }
2191 }
2192
2193 /*
2194 * void *restarter_contract_event_thread(void *)
2195 * Listens to the process contract bundle for critical events, taking action
2196 * on events from contracts we know we are responsible for.
2197 */
2198 /*ARGSUSED*/
2199 static void *
2200 restarter_contracts_event_thread(void *unused)
2201 {
2202 int fd, err;
2203 scf_handle_t *local_handle;
2204
2205 (void) pthread_setname_np(pthread_self(), "restarter_contracts_event");
2206
2207 /*
2208 * Await graph load completion. That is, stop here, until we've scanned
2209 * the repository for contract - instance associations.
2210 */
2211 MUTEX_LOCK(&st->st_load_lock);
2212 while (!(st->st_load_complete && st->st_load_instances == 0))
2213 (void) pthread_cond_wait(&st->st_load_cv, &st->st_load_lock);
2214 MUTEX_UNLOCK(&st->st_load_lock);
2215
2216 /*
2217 * This is a new thread, and thus, gets its own handle
2218 * to the repository.
2219 */
2220 if ((local_handle = libscf_handle_create_bound(SCF_VERSION)) == NULL)
2221 uu_die("Unable to bind a new repository handle: %s\n",
2222 scf_strerror(scf_error()));
2223
2224 fd = open64(CTFS_ROOT "/process/pbundle", O_RDONLY);
2225 if (fd == -1)
2226 uu_die("process bundle open failed");
2536
2537 return (ret);
2538 }
2539
2540 /*
2541 * void *restarter_timeouts_event_thread(void *)
2542 * Responsible for monitoring the method timeouts. This thread must
2543 * be started before any methods are called.
2544 */
2545 /*ARGSUSED*/
2546 static void *
2547 restarter_timeouts_event_thread(void *unused)
2548 {
2549 /*
2550 * Timeouts are entered on a priority queue, which is processed by
2551 * this thread. As timeouts are specified in seconds, we'll do
2552 * the necessary processing every second, as long as the queue
2553 * is not empty.
2554 */
2555
2556 (void) pthread_setname_np(pthread_self(), "restarter_timeouts_event");
2557
2558 /*CONSTCOND*/
2559 while (1) {
2560 /*
2561 * As long as the timeout list isn't empty, process it
2562 * every second.
2563 */
2564 if (timeout_now() == 0) {
2565 (void) sleep(1);
2566 continue;
2567 }
2568
2569 /* The list is empty, wait until we have more timeouts. */
2570 MUTEX_LOCK(&tu->tu_lock);
2571
2572 while (tu->tu_wakeup == 0)
2573 (void) pthread_cond_wait(&tu->tu_cv, &tu->tu_lock);
2574
2575 tu->tu_wakeup = 0;
2576 MUTEX_UNLOCK(&tu->tu_lock);
2577 }
|