Print this page
12721 would like svcadm disable -c


   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 2019 Joyent, Inc.
  25  * Copyright (c) 2015, 2016 by Delphix. All rights reserved.
  26  */
  27 
  28 /*
  29  * svcs - display attributes of service instances
  30  *
  31  * We have two output formats and six instance selection mechanisms.  The
  32  * primary output format is a line of attributes (selected by -o), possibly
  33  * followed by process description lines (if -p is specified), for each
  34  * instance selected.  The columns available to display are described by the
  35  * struct column columns array.  The columns to actually display are kept in
  36  * the opt_columns array as indicies into the columns array.  The selection
  37  * mechanisms available for this format are service FMRIs (selects all child
  38  * instances), instance FMRIs, instance FMRI glob patterns, instances with
  39  * a certain restarter (-R), dependencies of instances (-d), and dependents of
  40  * instances (-D).  Since the lines must be sorted (per -sS), we'll just stick
  41  * each into a data structure and print them in order when we're done.  To
  42  * avoid listing the same instance twice (when -d and -D aren't given), we'll
  43  * use a hash table of FMRIs to record that we've listed (added to the tree)
  44  * an instance.


  70 #include <libscf.h>
  71 #include <libscf_priv.h>
  72 #include <libuutil.h>
  73 #include <libnvpair.h>
  74 #include <libproc.h>
  75 #include <locale.h>
  76 #include <stdarg.h>
  77 #include <stdio.h>
  78 #include <stdlib.h>
  79 #include <strings.h>
  80 #include <time.h>
  81 #include <libzonecfg.h>
  82 #include <zone.h>
  83 
  84 #ifndef TEXT_DOMAIN
  85 #define TEXT_DOMAIN     "SUNW_OST_OSCMD"
  86 #endif /* TEXT_DOMAIN */
  87 
  88 #define LEGACY_UNKNOWN  "unknown"
  89 
  90 /* Flags for pg_get_single_val() */
  91 #define EMPTY_OK        0x01
  92 #define MULTI_OK        0x02
  93 
  94 /*
  95  * Per proc(4) when pr_nlwp, pr_nzomb, and pr_lwp.pr_lwpid are all 0,
  96  * the process is a zombie.
  97  */
  98 #define IS_ZOMBIE(_psip) \
  99         ((_psip)->pr_nlwp == 0 && (_psip)->pr_nzomb == 0 && \
 100         (_psip)->pr_lwp.pr_lwpid == 0)
 101 
 102 /*
 103  * An AVL-storable node for output lines and the keys to sort them by.
 104  */
 105 struct avl_string {
 106         uu_avl_node_t   node;
 107         char            *key;
 108         char            *str;
 109 };
 110 
 111 /*
 112  * For lists of parsed restarter FMRIs.
 113  */


 392                 case SCF_ERROR_NOT_FOUND:
 393                         if (flags & EMPTY_OK)
 394                                 goto out;
 395                         goto misconfigured;
 396 
 397                 case SCF_ERROR_CONSTRAINT_VIOLATED:
 398                         if (flags & MULTI_OK) {
 399                                 multi = B_TRUE;
 400                                 break;
 401                         }
 402                         goto misconfigured;
 403 
 404                 case SCF_ERROR_PERMISSION_DENIED:
 405                 default:
 406                         scfdie();
 407                 }
 408         }
 409 
 410         switch (ty) {
 411         case SCF_TYPE_ASTRING:
 412                 r = scf_value_get_astring(g_val, vp, sz) > 0 ? SCF_SUCCESS : -1;






 413                 break;
 414 
 415         case SCF_TYPE_BOOLEAN:
 416                 r = scf_value_get_boolean(g_val, (uint8_t *)vp);
 417                 break;
 418 
 419         case SCF_TYPE_COUNT:
 420                 r = scf_value_get_count(g_val, (uint64_t *)vp);
 421                 break;
 422 
 423         case SCF_TYPE_INTEGER:
 424                 r = scf_value_get_integer(g_val, (int64_t *)vp);
 425                 break;
 426 
 427         case SCF_TYPE_TIME: {
 428                 int64_t sec;
 429                 int32_t ns;
 430                 r = scf_value_get_time(g_val, &sec, &ns);
 431                 ((struct timeval *)vp)->tv_sec = sec;
 432                 ((struct timeval *)vp)->tv_usec = ns / 1000;


2460          * implementation from the user.  If the service has been temporarily
2461          * set to a state other than its permanent value, alert the user with
2462          * a '(temporary)' message.
2463          */
2464         perm = instance_enabled(wip->inst, B_FALSE);
2465         temp = instance_enabled(wip->inst, B_TRUE);
2466         if (temp != -1) {
2467                 if (temp != perm)
2468                         (void) printf(gettext("%-*s%s (temporary)\n"),
2469                             DETAILED_WIDTH, gettext("enabled"),
2470                             temp ? gettext("true") : gettext("false"));
2471                 else
2472                         (void) printf(fmt, DETAILED_WIDTH,
2473                             gettext("enabled"), temp ? gettext("true") :
2474                             gettext("false"));
2475         } else if (perm != -1) {
2476                 (void) printf(fmt, DETAILED_WIDTH, gettext("enabled"),
2477                     perm ? gettext("true") : gettext("false"));
2478         }
2479 















2480         /*
2481          * Property values may be longer than max_scf_fmri_length, but these
2482          * shouldn't be, so we'll just reuse buf.  The user can use svcprop if
2483          * they suspect something fishy.
2484          */
2485         if (scf_instance_get_pg(wip->inst, SCF_PG_RESTARTER, rpg) != 0) {
2486                 if (scf_error() != SCF_ERROR_NOT_FOUND)
2487                         scfdie();
2488 
2489                 scf_pg_destroy(rpg);
2490                 rpg = NULL;
2491         }
2492 
2493         if (rpg) {
2494                 if (pg_get_single_val(rpg, scf_property_state, SCF_TYPE_ASTRING,
2495                     buf, max_scf_fmri_length + 1, 0) == 0)
2496                         (void) printf(fmt, DETAILED_WIDTH, gettext("state"),
2497                             buf);
2498 
2499                 if (pg_get_single_val(rpg, scf_property_next_state,




   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 2020 Joyent, Inc.
  25  * Copyright (c) 2015, 2016 by Delphix. All rights reserved.
  26  */
  27 
  28 /*
  29  * svcs - display attributes of service instances
  30  *
  31  * We have two output formats and six instance selection mechanisms.  The
  32  * primary output format is a line of attributes (selected by -o), possibly
  33  * followed by process description lines (if -p is specified), for each
  34  * instance selected.  The columns available to display are described by the
  35  * struct column columns array.  The columns to actually display are kept in
  36  * the opt_columns array as indicies into the columns array.  The selection
  37  * mechanisms available for this format are service FMRIs (selects all child
  38  * instances), instance FMRIs, instance FMRI glob patterns, instances with
  39  * a certain restarter (-R), dependencies of instances (-d), and dependents of
  40  * instances (-D).  Since the lines must be sorted (per -sS), we'll just stick
  41  * each into a data structure and print them in order when we're done.  To
  42  * avoid listing the same instance twice (when -d and -D aren't given), we'll
  43  * use a hash table of FMRIs to record that we've listed (added to the tree)
  44  * an instance.


  70 #include <libscf.h>
  71 #include <libscf_priv.h>
  72 #include <libuutil.h>
  73 #include <libnvpair.h>
  74 #include <libproc.h>
  75 #include <locale.h>
  76 #include <stdarg.h>
  77 #include <stdio.h>
  78 #include <stdlib.h>
  79 #include <strings.h>
  80 #include <time.h>
  81 #include <libzonecfg.h>
  82 #include <zone.h>
  83 
  84 #ifndef TEXT_DOMAIN
  85 #define TEXT_DOMAIN     "SUNW_OST_OSCMD"
  86 #endif /* TEXT_DOMAIN */
  87 
  88 #define LEGACY_UNKNOWN  "unknown"
  89 




  90 /*
  91  * Per proc(4) when pr_nlwp, pr_nzomb, and pr_lwp.pr_lwpid are all 0,
  92  * the process is a zombie.
  93  */
  94 #define IS_ZOMBIE(_psip) \
  95         ((_psip)->pr_nlwp == 0 && (_psip)->pr_nzomb == 0 && \
  96         (_psip)->pr_lwp.pr_lwpid == 0)
  97 
  98 /*
  99  * An AVL-storable node for output lines and the keys to sort them by.
 100  */
 101 struct avl_string {
 102         uu_avl_node_t   node;
 103         char            *key;
 104         char            *str;
 105 };
 106 
 107 /*
 108  * For lists of parsed restarter FMRIs.
 109  */


 388                 case SCF_ERROR_NOT_FOUND:
 389                         if (flags & EMPTY_OK)
 390                                 goto out;
 391                         goto misconfigured;
 392 
 393                 case SCF_ERROR_CONSTRAINT_VIOLATED:
 394                         if (flags & MULTI_OK) {
 395                                 multi = B_TRUE;
 396                                 break;
 397                         }
 398                         goto misconfigured;
 399 
 400                 case SCF_ERROR_PERMISSION_DENIED:
 401                 default:
 402                         scfdie();
 403                 }
 404         }
 405 
 406         switch (ty) {
 407         case SCF_TYPE_ASTRING:
 408                 r = scf_value_get_astring(g_val, vp, sz);
 409                 if (r == 0 && !(flags & EMPTY_OK)) {
 410                         uu_die(gettext("Unexpected empty string for property "
 411                             "%s.  Exiting.\n"), propname);
 412                 }
 413                 if (r >= 0)
 414                         r = SCF_SUCCESS;
 415                 break;
 416 
 417         case SCF_TYPE_BOOLEAN:
 418                 r = scf_value_get_boolean(g_val, (uint8_t *)vp);
 419                 break;
 420 
 421         case SCF_TYPE_COUNT:
 422                 r = scf_value_get_count(g_val, (uint64_t *)vp);
 423                 break;
 424 
 425         case SCF_TYPE_INTEGER:
 426                 r = scf_value_get_integer(g_val, (int64_t *)vp);
 427                 break;
 428 
 429         case SCF_TYPE_TIME: {
 430                 int64_t sec;
 431                 int32_t ns;
 432                 r = scf_value_get_time(g_val, &sec, &ns);
 433                 ((struct timeval *)vp)->tv_sec = sec;
 434                 ((struct timeval *)vp)->tv_usec = ns / 1000;


2462          * implementation from the user.  If the service has been temporarily
2463          * set to a state other than its permanent value, alert the user with
2464          * a '(temporary)' message.
2465          */
2466         perm = instance_enabled(wip->inst, B_FALSE);
2467         temp = instance_enabled(wip->inst, B_TRUE);
2468         if (temp != -1) {
2469                 if (temp != perm)
2470                         (void) printf(gettext("%-*s%s (temporary)\n"),
2471                             DETAILED_WIDTH, gettext("enabled"),
2472                             temp ? gettext("true") : gettext("false"));
2473                 else
2474                         (void) printf(fmt, DETAILED_WIDTH,
2475                             gettext("enabled"), temp ? gettext("true") :
2476                             gettext("false"));
2477         } else if (perm != -1) {
2478                 (void) printf(fmt, DETAILED_WIDTH, gettext("enabled"),
2479                     perm ? gettext("true") : gettext("false"));
2480         }
2481 
2482         if (temp == 0 || (temp == -1 && perm == 0)) {
2483                 char comment[SCF_COMMENT_MAX_LENGTH] = "";
2484                 const char *pg = (temp != -1 && temp != perm) ?
2485                     SCF_PG_GENERAL_OVR : SCF_PG_GENERAL;
2486 
2487                 (void) inst_get_single_val(wip->inst, pg, SCF_PROPERTY_COMMENT,
2488                     SCF_TYPE_ASTRING, &comment, sizeof (comment),
2489                     EMPTY_OK, 0, 0);
2490 
2491                 if (comment[0] != '\0') {
2492                         printf(fmt, DETAILED_WIDTH, gettext("comment"),
2493                             comment);
2494                 }
2495         }
2496 
2497         /*
2498          * Property values may be longer than max_scf_fmri_length, but these
2499          * shouldn't be, so we'll just reuse buf.  The user can use svcprop if
2500          * they suspect something fishy.
2501          */
2502         if (scf_instance_get_pg(wip->inst, SCF_PG_RESTARTER, rpg) != 0) {
2503                 if (scf_error() != SCF_ERROR_NOT_FOUND)
2504                         scfdie();
2505 
2506                 scf_pg_destroy(rpg);
2507                 rpg = NULL;
2508         }
2509 
2510         if (rpg) {
2511                 if (pg_get_single_val(rpg, scf_property_state, SCF_TYPE_ASTRING,
2512                     buf, max_scf_fmri_length + 1, 0) == 0)
2513                         (void) printf(fmt, DETAILED_WIDTH, gettext("state"),
2514                             buf);
2515 
2516                 if (pg_get_single_val(rpg, scf_property_next_state,