Print this page
3315 svccfg export -a drops values in PG "general"
Reviewed by: Eric Schrock <eric.schrock@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>


9064                          * service_fmri's must be first, so we can add them
9065                          * here.
9066                          */
9067                         ch = xmlNewChild(n, NULL, (xmlChar *)"service_fmri",
9068                             NULL);
9069                         if (ch == NULL)
9070                                 uu_die(emsg_create_xml);
9071 
9072                         safe_setprop(ch, value_attr, exp_str);
9073                 }
9074                 if (ret2 == -1)
9075                         scfdie();
9076 
9077                 scf_iter_destroy(eiter);
9078         } else
9079                 err = 1;
9080 
9081         if (err) {
9082                 xmlFreeNode(n);
9083 
9084                 export_pg(pg, eelts, 0);
9085 
9086                 return;
9087         }
9088 
9089         /* Iterate through the properties & handle each. */
9090         if (scf_iter_pg_properties(exp_prop_iter, pg) != SCF_SUCCESS)
9091                 scfdie();
9092 
9093         (void) memset(&elts, 0, sizeof (elts));
9094 
9095         while ((ret = scf_iter_next_property(exp_prop_iter, exp_prop)) == 1) {
9096                 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9097                         scfdie();
9098 
9099                 if (strcmp(exp_str, SCF_PROPERTY_GROUPING) == 0 ||
9100                     strcmp(exp_str, SCF_PROPERTY_RESTART_ON) == 0 ||
9101                     strcmp(exp_str, SCF_PROPERTY_TYPE) == 0 ||
9102                     strcmp(exp_str, SCF_PROPERTY_ENTITIES) == 0) {
9103                         continue;
9104                 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9105                         xmlNodePtr m;
9106 
9107                         m = xmlNewNode(NULL, (xmlChar *)"stability");
9108                         if (m == NULL)
9109                                 uu_die(emsg_create_xml);
9110 
9111                         if (set_attr_from_prop(exp_prop, m, value_attr) == 0) {
9112                                 elts.stability = m;
9113                                 continue;
9114                         }
9115 
9116                         xmlFreeNode(m);
9117                 }
9118 
9119                 export_property(exp_prop, exp_str, &elts, 0);
9120         }
9121         if (ret == -1)
9122                 scfdie();
9123 
9124         (void) xmlAddChild(n, elts.stability);
9125         (void) xmlAddChildList(n, elts.propvals);
9126         (void) xmlAddChildList(n, elts.properties);
9127 
9128         if (eelts->dependencies == NULL)
9129                 eelts->dependencies = n;
9130         else
9131                 (void) xmlAddSibling(eelts->dependencies, n);
9132 }
9133 
9134 static xmlNodePtr
9135 export_method_environment(scf_propertygroup_t *pg)
9136 {
9137         xmlNodePtr env;
9138         int ret;
9139         int children = 0;


9227         if (pg_get_prop(pg, SCF_PROPERTY_TIMEOUT, exp_prop) == 0 &&
9228             prop_check_type(exp_prop, SCF_TYPE_COUNT) == 0 &&
9229             prop_get_val(exp_prop, exp_val) == 0) {
9230                 uint64_t c;
9231 
9232                 if (scf_value_get_count(exp_val, &c) != SCF_SUCCESS)
9233                         scfdie();
9234 
9235                 str = uu_msprintf("%llu", c);
9236                 if (str == NULL)
9237                         uu_die(gettext("Could not create string"));
9238 
9239                 safe_setprop(n, "timeout_seconds", str);
9240                 free(str);
9241         } else
9242                 err = 1;
9243 
9244         if (err) {
9245                 xmlFreeNode(n);
9246 
9247                 export_pg(pg, eelts, 0);
9248 
9249                 return;
9250         }
9251 
9252 
9253         /*
9254          * If we're going to have a method_context child, we need to know
9255          * before we iterate through the properties.  Since method_context's
9256          * are optional, we don't want to complain about any properties
9257          * missing if none of them are there.  Thus we can't use the
9258          * convenience functions.
9259          */
9260         nonenv =
9261             scf_pg_get_property(pg, SCF_PROPERTY_WORKING_DIRECTORY, NULL) ==
9262             SCF_SUCCESS ||
9263             scf_pg_get_property(pg, SCF_PROPERTY_PROJECT, NULL) ==
9264             SCF_SUCCESS ||
9265             scf_pg_get_property(pg, SCF_PROPERTY_RESOURCE_POOL, NULL) ==
9266             SCF_SUCCESS ||
9267             scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, NULL) ==


9404                     strcmp(exp_str, SCF_PROPERTY_PROJECT) == 0 ||
9405                     strcmp(exp_str, SCF_PROPERTY_RESOURCE_POOL) == 0 ||
9406                     strcmp(exp_str, SCF_PROPERTY_USE_PROFILE) == 0) {
9407                         if (nonenv)
9408                                 continue;
9409                 } else if (strcmp(exp_str, SCF_PROPERTY_USER) == 0 ||
9410                     strcmp(exp_str, SCF_PROPERTY_GROUP) == 0 ||
9411                     strcmp(exp_str, SCF_PROPERTY_SUPP_GROUPS) == 0 ||
9412                     strcmp(exp_str, SCF_PROPERTY_PRIVILEGES) == 0 ||
9413                     strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) == 0) {
9414                         if (nonenv && !use_profile)
9415                                 continue;
9416                 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9417                         if (nonenv && use_profile)
9418                                 continue;
9419                 } else if (strcmp(exp_str, SCF_PROPERTY_ENVIRONMENT) == 0) {
9420                         if (env != NULL)
9421                                 continue;
9422                 }
9423 
9424                 export_property(exp_prop, exp_str, &elts, 0);
9425         }
9426         if (ret == -1)
9427                 scfdie();
9428 
9429         (void) xmlAddChild(n, elts.stability);
9430         (void) xmlAddChildList(n, elts.propvals);
9431         (void) xmlAddChildList(n, elts.properties);
9432 
9433         if (eelts->exec_methods == NULL)
9434                 eelts->exec_methods = n;
9435         else
9436                 (void) xmlAddSibling(eelts->exec_methods, n);
9437 }
9438 
9439 static void
9440 export_pg_elts(struct pg_elts *elts, const char *name, const char *type,
9441     struct entity_elts *eelts)
9442 {
9443         xmlNodePtr pgnode;
9444 


9520                                 continue;
9521                         }
9522 
9523                         xmlFreeNode(rnode);
9524                 } else if (strcmp(exp_str, SCF_PROPERTY_ENTITY_STABILITY) ==
9525                     0) {
9526                         xmlNodePtr s;
9527 
9528                         s = xmlNewNode(NULL, (xmlChar *)"stability");
9529                         if (s == NULL)
9530                                 uu_die(emsg_create_xml);
9531 
9532                         if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9533                                 selts->stability = s;
9534                                 continue;
9535                         }
9536 
9537                         xmlFreeNode(s);
9538                 }
9539 
9540                 export_property(exp_prop, exp_str, &elts, 0);
9541         }
9542         if (ret == -1)
9543                 scfdie();
9544 
9545         if (elts.propvals != NULL || elts.properties != NULL)
9546                 export_pg_elts(&elts, scf_pg_general, scf_group_framework,
9547                     selts);
9548 }
9549 
9550 static void
9551 export_method_context(scf_propertygroup_t *pg, struct entity_elts *elts)
9552 {
9553         xmlNodePtr n, prof, cred, env;
9554         uint8_t use_profile;
9555         int ret, err = 0;
9556 
9557         n = xmlNewNode(NULL, (xmlChar *)"method_context");
9558 
9559         env = export_method_environment(pg);
9560 


9616                                 err = 1;
9617                 } else if (strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) ==
9618                     0) {
9619                         if (use_profile || set_attr_from_prop(exp_prop, cred,
9620                             "limit_privileges") != 0)
9621                                 err = 1;
9622                 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9623                         if (!use_profile || set_attr_from_prop(exp_prop,
9624                             prof, name_attr) != 0)
9625                                 err = 1;
9626                 } else {
9627                         /* Can't have generic properties in method_context's */
9628                         err = 1;
9629                 }
9630         }
9631         if (ret == -1)
9632                 scfdie();
9633 
9634         if (err && env == NULL) {
9635                 xmlFreeNode(n);
9636                 export_pg(pg, elts, 0);
9637                 return;
9638         }
9639 
9640         elts->method_context = n;
9641 }
9642 
9643 /*
9644  * Given a dependency property group in the tfmri entity (target fmri), return
9645  * a dependent element which represents it.
9646  */
9647 static xmlNodePtr
9648 export_dependent(scf_propertygroup_t *pg, const char *name, const char *tfmri)
9649 {
9650         uint8_t b;
9651         xmlNodePtr n, sf;
9652         int err = 0, ret;
9653         struct pg_elts pgelts;
9654 
9655         /*
9656          * If external isn't set to true then exporting the service will


9730                                         scfdie();
9731 
9732                                 if (strcmp(type, "service") == 0)
9733                                         continue;
9734                         }
9735                 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9736                         xmlNodePtr s;
9737 
9738                         s = xmlNewNode(NULL, (xmlChar *)"stability");
9739                         if (s == NULL)
9740                                 uu_die(emsg_create_xml);
9741 
9742                         if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9743                                 pgelts.stability = s;
9744                                 continue;
9745                         }
9746 
9747                         xmlFreeNode(s);
9748                 }
9749 
9750                 export_property(exp_prop, exp_str, &pgelts, 0);
9751         }
9752         if (ret == -1)
9753                 scfdie();
9754 
9755         (void) xmlAddChild(n, pgelts.stability);
9756         (void) xmlAddChildList(n, pgelts.propvals);
9757         (void) xmlAddChildList(n, pgelts.properties);
9758 
9759         return (n);
9760 }
9761 
9762 static void
9763 export_dependents(scf_propertygroup_t *pg, struct entity_elts *eelts)
9764 {
9765         scf_propertygroup_t *opg;
9766         scf_iter_t *iter;
9767         char *type, *fmri;
9768         int ret;
9769         struct pg_elts pgelts;
9770         xmlNodePtr n;


9779                 scfdie();
9780 
9781         type = safe_malloc(max_scf_pg_type_len + 1);
9782 
9783         /* Get an extra byte so we can tell if values are too long. */
9784         fmri = safe_malloc(max_scf_fmri_len + 2);
9785 
9786         (void) memset(&pgelts, 0, sizeof (pgelts));
9787 
9788         while ((ret = scf_iter_next_property(iter, exp_prop)) == 1) {
9789                 void *entity;
9790                 int isservice;
9791                 scf_type_t ty;
9792 
9793                 if (scf_property_type(exp_prop, &ty) != SCF_SUCCESS)
9794                         scfdie();
9795 
9796                 if ((ty != SCF_TYPE_ASTRING &&
9797                     prop_check_type(exp_prop, SCF_TYPE_FMRI) != 0) ||
9798                     prop_get_val(exp_prop, exp_val) != 0) {
9799                         export_property(exp_prop, NULL, &pgelts, 0);

9800                         continue;
9801                 }
9802 
9803                 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9804                         scfdie();
9805 
9806                 if (scf_value_get_astring(exp_val, fmri,
9807                     max_scf_fmri_len + 2) < 0)
9808                         scfdie();
9809 
9810                 /* Look for a dependency group in the target fmri. */
9811                 serr = fmri_to_entity(g_hndl, fmri, &entity, &isservice);
9812                 switch (serr) {
9813                 case SCF_ERROR_NONE:
9814                         break;
9815 
9816                 case SCF_ERROR_NO_MEMORY:
9817                         uu_die(gettext("Out of memory.\n"));
9818                         /* NOTREACHED */
9819 
9820                 case SCF_ERROR_INVALID_ARGUMENT:
9821                         if (g_verbose) {
9822                                 if (scf_property_to_fmri(exp_prop, fmri,
9823                                     max_scf_fmri_len + 2) < 0)
9824                                         scfdie();
9825 
9826                                 warn(gettext("The value of %s is not a valid "
9827                                     "FMRI.\n"), fmri);
9828                         }
9829 
9830                         export_property(exp_prop, exp_str, &pgelts, 0);

9831                         continue;
9832 
9833                 case SCF_ERROR_CONSTRAINT_VIOLATED:
9834                         if (g_verbose) {
9835                                 if (scf_property_to_fmri(exp_prop, fmri,
9836                                     max_scf_fmri_len + 2) < 0)
9837                                         scfdie();
9838 
9839                                 warn(gettext("The value of %s does not specify "
9840                                     "a service or an instance.\n"), fmri);
9841                         }
9842 
9843                         export_property(exp_prop, exp_str, &pgelts, 0);

9844                         continue;
9845 
9846                 case SCF_ERROR_NOT_FOUND:
9847                         if (g_verbose) {
9848                                 if (scf_property_to_fmri(exp_prop, fmri,
9849                                     max_scf_fmri_len + 2) < 0)
9850                                         scfdie();
9851 
9852                                 warn(gettext("The entity specified by %s does "
9853                                     "not exist.\n"), fmri);
9854                         }
9855 
9856                         export_property(exp_prop, exp_str, &pgelts, 0);

9857                         continue;
9858 
9859                 default:
9860 #ifndef NDEBUG
9861                         (void) fprintf(stderr, "%s:%d: %s() failed with "
9862                             "unexpected error %d.\n", __FILE__, __LINE__,
9863                             "fmri_to_entity", serr);
9864 #endif
9865                         abort();
9866                 }
9867 
9868                 if (entity_get_pg(entity, isservice, exp_str, opg) != 0) {
9869                         if (scf_error() != SCF_ERROR_NOT_FOUND)
9870                                 scfdie();
9871 
9872                         warn(gettext("Entity %s is missing dependency property "
9873                             "group %s.\n"), fmri, exp_str);
9874 
9875                         export_property(exp_prop, NULL, &pgelts, 0);

9876                         continue;
9877                 }
9878 
9879                 if (scf_pg_get_type(opg, type, max_scf_pg_type_len + 1) < 0)
9880                         scfdie();
9881 
9882                 if (strcmp(type, SCF_GROUP_DEPENDENCY) != 0) {
9883                         if (scf_pg_to_fmri(opg, fmri, max_scf_fmri_len + 2) < 0)
9884                                 scfdie();
9885 
9886                         warn(gettext("Property group %s is not of "
9887                             "expected type %s.\n"), fmri, SCF_GROUP_DEPENDENCY);
9888 
9889                         export_property(exp_prop, NULL, &pgelts, 0);

9890                         continue;
9891                 }
9892 
9893                 n = export_dependent(opg, exp_str, fmri);
9894                 if (n == NULL)
9895                         export_property(exp_prop, exp_str, &pgelts, 0);
9896                 else {

9897                         if (eelts->dependents == NULL)
9898                                 eelts->dependents = n;
9899                         else
9900                                 (void) xmlAddSibling(eelts->dependents,
9901                                     n);
9902                 }
9903         }
9904         if (ret == -1)
9905                 scfdie();
9906 
9907         free(fmri);
9908         free(type);
9909 
9910         scf_iter_destroy(iter);
9911         scf_pg_destroy(opg);
9912 
9913         if (pgelts.propvals != NULL || pgelts.properties != NULL)
9914                 export_pg_elts(&pgelts, SCF_PG_DEPENDENTS, scf_group_framework,
9915                     eelts);
9916 }


10000         return (doc_link);
10001 }
10002 
10003 /*
10004  * Process template information for a service or instances.
10005  */
10006 static void
10007 export_template(scf_propertygroup_t *pg, struct entity_elts *elts,
10008     struct template_elts *telts)
10009 {
10010         size_t mansz = strlen(SCF_PG_TM_MAN_PREFIX);
10011         size_t docsz = strlen(SCF_PG_TM_DOC_PREFIX);
10012         xmlNodePtr child = NULL;
10013 
10014         if (scf_pg_get_name(pg, exp_str, exp_str_sz) < 0)
10015                 scfdie();
10016 
10017         if (strcmp(exp_str, SCF_PG_TM_COMMON_NAME) == 0) {
10018                 telts->common_name = export_tm_loctext(pg, "common_name");
10019                 if (telts->common_name == NULL)
10020                         export_pg(pg, elts, 0);
10021                 return;
10022         } else if (strcmp(exp_str, SCF_PG_TM_DESCRIPTION) == 0) {
10023                 telts->description = export_tm_loctext(pg, "description");
10024                 if (telts->description == NULL)
10025                         export_pg(pg, elts, 0);
10026                 return;
10027         }
10028 
10029         if (strncmp(exp_str, SCF_PG_TM_MAN_PREFIX, mansz) == 0) {
10030                 child = export_tm_manpage(pg);
10031         } else if (strncmp(exp_str, SCF_PG_TM_DOC_PREFIX, docsz) == 0) {
10032                 child = export_tm_doc_link(pg);
10033         }
10034 
10035         if (child != NULL) {
10036                 make_node(&telts->documentation, "documentation");
10037                 (void) xmlAddChild(telts->documentation, child);
10038         } else {
10039                 export_pg(pg, elts, 0);
10040         }
10041 }
10042 
10043 /*
10044  * Process parameter and paramval elements
10045  */
10046 static void
10047 export_parameter(scf_property_t *prop, const char *name,
10048     struct params_elts *elts)
10049 {
10050         xmlNodePtr param;
10051         scf_error_t err = 0;
10052         int ret;
10053 
10054         if (scf_property_get_value(prop, exp_val) == SCF_SUCCESS) {
10055                 if ((param = xmlNewNode(NULL, (xmlChar *)"paramval")) == NULL)
10056                         uu_die(emsg_create_xml);
10057 
10058                 safe_setprop(param, name_attr, name);
10059 


10172                             active_attr) != 0) {
10173                                 err = 1;
10174                                 break;
10175                         }
10176                         continue;
10177                 }
10178                 /*
10179                  * We export the parameter
10180                  */
10181                 export_parameter(exp_prop, p, &eelts[i]);
10182         }
10183 
10184         if (ret == -1)
10185                 scfdie();
10186 
10187         if (err == 1) {
10188                 for (i = 0; i < URI_SCHEME_NUM; ++i)
10189                         xmlFree(type[i]);
10190                 free(type);
10191 
10192                 export_pg(pg, elts, 0);
10193 
10194                 return;
10195         } else {
10196                 for (i = 0; i < URI_SCHEME_NUM; ++i)
10197                         if (type[i] != NULL) {
10198                                 (void) xmlAddChildList(type[i],
10199                                     eelts[i].paramval);
10200                                 (void) xmlAddChildList(type[i],
10201                                     eelts[i].parameter);
10202                                 (void) xmlAddSibling(event, type[i]);
10203                         }
10204         }
10205         free(type);
10206 
10207         if (elts->notify_params == NULL)
10208                 elts->notify_params = n;
10209         else
10210                 (void) xmlAddSibling(elts->notify_params, n);
10211 }
10212 


10248                         xmlNodePtr rnode, sfnode;
10249 
10250                         rnode = xmlNewNode(NULL, (xmlChar *)"restarter");
10251                         if (rnode == NULL)
10252                                 uu_die(emsg_create_xml);
10253 
10254                         sfnode = xmlNewChild(rnode, NULL,
10255                             (xmlChar *)"service_fmri", NULL);
10256                         if (sfnode == NULL)
10257                                 uu_die(emsg_create_xml);
10258 
10259                         if (set_attr_from_prop(exp_prop, sfnode,
10260                             value_attr) == 0) {
10261                                 elts->restarter = rnode;
10262                                 continue;
10263                         }
10264 
10265                         xmlFreeNode(rnode);
10266                 }
10267 
10268                 export_property(exp_prop, exp_str, &pgelts, 0);
10269         }
10270         if (ret == -1)
10271                 scfdie();
10272 
10273         if (pgelts.propvals != NULL || pgelts.properties != NULL)
10274                 export_pg_elts(&pgelts, scf_pg_general, scf_group_framework,
10275                     elts);
10276 }
10277 
10278 /*
10279  * Put an instance element for the given instance into selts.
10280  */
10281 static void
10282 export_instance(scf_instance_t *inst, struct entity_elts *selts, int flags)
10283 {
10284         xmlNodePtr n;
10285         boolean_t isdefault;
10286         struct entity_elts elts;
10287         struct template_elts template_elts;
10288         int ret;




9064                          * service_fmri's must be first, so we can add them
9065                          * here.
9066                          */
9067                         ch = xmlNewChild(n, NULL, (xmlChar *)"service_fmri",
9068                             NULL);
9069                         if (ch == NULL)
9070                                 uu_die(emsg_create_xml);
9071 
9072                         safe_setprop(ch, value_attr, exp_str);
9073                 }
9074                 if (ret2 == -1)
9075                         scfdie();
9076 
9077                 scf_iter_destroy(eiter);
9078         } else
9079                 err = 1;
9080 
9081         if (err) {
9082                 xmlFreeNode(n);
9083 
9084                 export_pg(pg, eelts, SCE_ALL_VALUES);
9085 
9086                 return;
9087         }
9088 
9089         /* Iterate through the properties & handle each. */
9090         if (scf_iter_pg_properties(exp_prop_iter, pg) != SCF_SUCCESS)
9091                 scfdie();
9092 
9093         (void) memset(&elts, 0, sizeof (elts));
9094 
9095         while ((ret = scf_iter_next_property(exp_prop_iter, exp_prop)) == 1) {
9096                 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9097                         scfdie();
9098 
9099                 if (strcmp(exp_str, SCF_PROPERTY_GROUPING) == 0 ||
9100                     strcmp(exp_str, SCF_PROPERTY_RESTART_ON) == 0 ||
9101                     strcmp(exp_str, SCF_PROPERTY_TYPE) == 0 ||
9102                     strcmp(exp_str, SCF_PROPERTY_ENTITIES) == 0) {
9103                         continue;
9104                 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9105                         xmlNodePtr m;
9106 
9107                         m = xmlNewNode(NULL, (xmlChar *)"stability");
9108                         if (m == NULL)
9109                                 uu_die(emsg_create_xml);
9110 
9111                         if (set_attr_from_prop(exp_prop, m, value_attr) == 0) {
9112                                 elts.stability = m;
9113                                 continue;
9114                         }
9115 
9116                         xmlFreeNode(m);
9117                 }
9118 
9119                 export_property(exp_prop, exp_str, &elts, SCE_ALL_VALUES);
9120         }
9121         if (ret == -1)
9122                 scfdie();
9123 
9124         (void) xmlAddChild(n, elts.stability);
9125         (void) xmlAddChildList(n, elts.propvals);
9126         (void) xmlAddChildList(n, elts.properties);
9127 
9128         if (eelts->dependencies == NULL)
9129                 eelts->dependencies = n;
9130         else
9131                 (void) xmlAddSibling(eelts->dependencies, n);
9132 }
9133 
9134 static xmlNodePtr
9135 export_method_environment(scf_propertygroup_t *pg)
9136 {
9137         xmlNodePtr env;
9138         int ret;
9139         int children = 0;


9227         if (pg_get_prop(pg, SCF_PROPERTY_TIMEOUT, exp_prop) == 0 &&
9228             prop_check_type(exp_prop, SCF_TYPE_COUNT) == 0 &&
9229             prop_get_val(exp_prop, exp_val) == 0) {
9230                 uint64_t c;
9231 
9232                 if (scf_value_get_count(exp_val, &c) != SCF_SUCCESS)
9233                         scfdie();
9234 
9235                 str = uu_msprintf("%llu", c);
9236                 if (str == NULL)
9237                         uu_die(gettext("Could not create string"));
9238 
9239                 safe_setprop(n, "timeout_seconds", str);
9240                 free(str);
9241         } else
9242                 err = 1;
9243 
9244         if (err) {
9245                 xmlFreeNode(n);
9246 
9247                 export_pg(pg, eelts, SCE_ALL_VALUES);
9248 
9249                 return;
9250         }
9251 
9252 
9253         /*
9254          * If we're going to have a method_context child, we need to know
9255          * before we iterate through the properties.  Since method_context's
9256          * are optional, we don't want to complain about any properties
9257          * missing if none of them are there.  Thus we can't use the
9258          * convenience functions.
9259          */
9260         nonenv =
9261             scf_pg_get_property(pg, SCF_PROPERTY_WORKING_DIRECTORY, NULL) ==
9262             SCF_SUCCESS ||
9263             scf_pg_get_property(pg, SCF_PROPERTY_PROJECT, NULL) ==
9264             SCF_SUCCESS ||
9265             scf_pg_get_property(pg, SCF_PROPERTY_RESOURCE_POOL, NULL) ==
9266             SCF_SUCCESS ||
9267             scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, NULL) ==


9404                     strcmp(exp_str, SCF_PROPERTY_PROJECT) == 0 ||
9405                     strcmp(exp_str, SCF_PROPERTY_RESOURCE_POOL) == 0 ||
9406                     strcmp(exp_str, SCF_PROPERTY_USE_PROFILE) == 0) {
9407                         if (nonenv)
9408                                 continue;
9409                 } else if (strcmp(exp_str, SCF_PROPERTY_USER) == 0 ||
9410                     strcmp(exp_str, SCF_PROPERTY_GROUP) == 0 ||
9411                     strcmp(exp_str, SCF_PROPERTY_SUPP_GROUPS) == 0 ||
9412                     strcmp(exp_str, SCF_PROPERTY_PRIVILEGES) == 0 ||
9413                     strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) == 0) {
9414                         if (nonenv && !use_profile)
9415                                 continue;
9416                 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9417                         if (nonenv && use_profile)
9418                                 continue;
9419                 } else if (strcmp(exp_str, SCF_PROPERTY_ENVIRONMENT) == 0) {
9420                         if (env != NULL)
9421                                 continue;
9422                 }
9423 
9424                 export_property(exp_prop, exp_str, &elts, SCE_ALL_VALUES);
9425         }
9426         if (ret == -1)
9427                 scfdie();
9428 
9429         (void) xmlAddChild(n, elts.stability);
9430         (void) xmlAddChildList(n, elts.propvals);
9431         (void) xmlAddChildList(n, elts.properties);
9432 
9433         if (eelts->exec_methods == NULL)
9434                 eelts->exec_methods = n;
9435         else
9436                 (void) xmlAddSibling(eelts->exec_methods, n);
9437 }
9438 
9439 static void
9440 export_pg_elts(struct pg_elts *elts, const char *name, const char *type,
9441     struct entity_elts *eelts)
9442 {
9443         xmlNodePtr pgnode;
9444 


9520                                 continue;
9521                         }
9522 
9523                         xmlFreeNode(rnode);
9524                 } else if (strcmp(exp_str, SCF_PROPERTY_ENTITY_STABILITY) ==
9525                     0) {
9526                         xmlNodePtr s;
9527 
9528                         s = xmlNewNode(NULL, (xmlChar *)"stability");
9529                         if (s == NULL)
9530                                 uu_die(emsg_create_xml);
9531 
9532                         if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9533                                 selts->stability = s;
9534                                 continue;
9535                         }
9536 
9537                         xmlFreeNode(s);
9538                 }
9539 
9540                 export_property(exp_prop, exp_str, &elts, SCE_ALL_VALUES);
9541         }
9542         if (ret == -1)
9543                 scfdie();
9544 
9545         if (elts.propvals != NULL || elts.properties != NULL)
9546                 export_pg_elts(&elts, scf_pg_general, scf_group_framework,
9547                     selts);
9548 }
9549 
9550 static void
9551 export_method_context(scf_propertygroup_t *pg, struct entity_elts *elts)
9552 {
9553         xmlNodePtr n, prof, cred, env;
9554         uint8_t use_profile;
9555         int ret, err = 0;
9556 
9557         n = xmlNewNode(NULL, (xmlChar *)"method_context");
9558 
9559         env = export_method_environment(pg);
9560 


9616                                 err = 1;
9617                 } else if (strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) ==
9618                     0) {
9619                         if (use_profile || set_attr_from_prop(exp_prop, cred,
9620                             "limit_privileges") != 0)
9621                                 err = 1;
9622                 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9623                         if (!use_profile || set_attr_from_prop(exp_prop,
9624                             prof, name_attr) != 0)
9625                                 err = 1;
9626                 } else {
9627                         /* Can't have generic properties in method_context's */
9628                         err = 1;
9629                 }
9630         }
9631         if (ret == -1)
9632                 scfdie();
9633 
9634         if (err && env == NULL) {
9635                 xmlFreeNode(n);
9636                 export_pg(pg, elts, SCE_ALL_VALUES);
9637                 return;
9638         }
9639 
9640         elts->method_context = n;
9641 }
9642 
9643 /*
9644  * Given a dependency property group in the tfmri entity (target fmri), return
9645  * a dependent element which represents it.
9646  */
9647 static xmlNodePtr
9648 export_dependent(scf_propertygroup_t *pg, const char *name, const char *tfmri)
9649 {
9650         uint8_t b;
9651         xmlNodePtr n, sf;
9652         int err = 0, ret;
9653         struct pg_elts pgelts;
9654 
9655         /*
9656          * If external isn't set to true then exporting the service will


9730                                         scfdie();
9731 
9732                                 if (strcmp(type, "service") == 0)
9733                                         continue;
9734                         }
9735                 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9736                         xmlNodePtr s;
9737 
9738                         s = xmlNewNode(NULL, (xmlChar *)"stability");
9739                         if (s == NULL)
9740                                 uu_die(emsg_create_xml);
9741 
9742                         if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9743                                 pgelts.stability = s;
9744                                 continue;
9745                         }
9746 
9747                         xmlFreeNode(s);
9748                 }
9749 
9750                 export_property(exp_prop, exp_str, &pgelts, SCE_ALL_VALUES);
9751         }
9752         if (ret == -1)
9753                 scfdie();
9754 
9755         (void) xmlAddChild(n, pgelts.stability);
9756         (void) xmlAddChildList(n, pgelts.propvals);
9757         (void) xmlAddChildList(n, pgelts.properties);
9758 
9759         return (n);
9760 }
9761 
9762 static void
9763 export_dependents(scf_propertygroup_t *pg, struct entity_elts *eelts)
9764 {
9765         scf_propertygroup_t *opg;
9766         scf_iter_t *iter;
9767         char *type, *fmri;
9768         int ret;
9769         struct pg_elts pgelts;
9770         xmlNodePtr n;


9779                 scfdie();
9780 
9781         type = safe_malloc(max_scf_pg_type_len + 1);
9782 
9783         /* Get an extra byte so we can tell if values are too long. */
9784         fmri = safe_malloc(max_scf_fmri_len + 2);
9785 
9786         (void) memset(&pgelts, 0, sizeof (pgelts));
9787 
9788         while ((ret = scf_iter_next_property(iter, exp_prop)) == 1) {
9789                 void *entity;
9790                 int isservice;
9791                 scf_type_t ty;
9792 
9793                 if (scf_property_type(exp_prop, &ty) != SCF_SUCCESS)
9794                         scfdie();
9795 
9796                 if ((ty != SCF_TYPE_ASTRING &&
9797                     prop_check_type(exp_prop, SCF_TYPE_FMRI) != 0) ||
9798                     prop_get_val(exp_prop, exp_val) != 0) {
9799                         export_property(exp_prop, NULL, &pgelts,
9800                             SCE_ALL_VALUES);
9801                         continue;
9802                 }
9803 
9804                 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9805                         scfdie();
9806 
9807                 if (scf_value_get_astring(exp_val, fmri,
9808                     max_scf_fmri_len + 2) < 0)
9809                         scfdie();
9810 
9811                 /* Look for a dependency group in the target fmri. */
9812                 serr = fmri_to_entity(g_hndl, fmri, &entity, &isservice);
9813                 switch (serr) {
9814                 case SCF_ERROR_NONE:
9815                         break;
9816 
9817                 case SCF_ERROR_NO_MEMORY:
9818                         uu_die(gettext("Out of memory.\n"));
9819                         /* NOTREACHED */
9820 
9821                 case SCF_ERROR_INVALID_ARGUMENT:
9822                         if (g_verbose) {
9823                                 if (scf_property_to_fmri(exp_prop, fmri,
9824                                     max_scf_fmri_len + 2) < 0)
9825                                         scfdie();
9826 
9827                                 warn(gettext("The value of %s is not a valid "
9828                                     "FMRI.\n"), fmri);
9829                         }
9830 
9831                         export_property(exp_prop, exp_str, &pgelts,
9832                             SCE_ALL_VALUES);
9833                         continue;
9834 
9835                 case SCF_ERROR_CONSTRAINT_VIOLATED:
9836                         if (g_verbose) {
9837                                 if (scf_property_to_fmri(exp_prop, fmri,
9838                                     max_scf_fmri_len + 2) < 0)
9839                                         scfdie();
9840 
9841                                 warn(gettext("The value of %s does not specify "
9842                                     "a service or an instance.\n"), fmri);
9843                         }
9844 
9845                         export_property(exp_prop, exp_str, &pgelts,
9846                             SCE_ALL_VALUES);
9847                         continue;
9848 
9849                 case SCF_ERROR_NOT_FOUND:
9850                         if (g_verbose) {
9851                                 if (scf_property_to_fmri(exp_prop, fmri,
9852                                     max_scf_fmri_len + 2) < 0)
9853                                         scfdie();
9854 
9855                                 warn(gettext("The entity specified by %s does "
9856                                     "not exist.\n"), fmri);
9857                         }
9858 
9859                         export_property(exp_prop, exp_str, &pgelts,
9860                             SCE_ALL_VALUES);
9861                         continue;
9862 
9863                 default:
9864 #ifndef NDEBUG
9865                         (void) fprintf(stderr, "%s:%d: %s() failed with "
9866                             "unexpected error %d.\n", __FILE__, __LINE__,
9867                             "fmri_to_entity", serr);
9868 #endif
9869                         abort();
9870                 }
9871 
9872                 if (entity_get_pg(entity, isservice, exp_str, opg) != 0) {
9873                         if (scf_error() != SCF_ERROR_NOT_FOUND)
9874                                 scfdie();
9875 
9876                         warn(gettext("Entity %s is missing dependency property "
9877                             "group %s.\n"), fmri, exp_str);
9878 
9879                         export_property(exp_prop, NULL, &pgelts,
9880                             SCE_ALL_VALUES);
9881                         continue;
9882                 }
9883 
9884                 if (scf_pg_get_type(opg, type, max_scf_pg_type_len + 1) < 0)
9885                         scfdie();
9886 
9887                 if (strcmp(type, SCF_GROUP_DEPENDENCY) != 0) {
9888                         if (scf_pg_to_fmri(opg, fmri, max_scf_fmri_len + 2) < 0)
9889                                 scfdie();
9890 
9891                         warn(gettext("Property group %s is not of "
9892                             "expected type %s.\n"), fmri, SCF_GROUP_DEPENDENCY);
9893 
9894                         export_property(exp_prop, NULL, &pgelts,
9895                             SCE_ALL_VALUES);
9896                         continue;
9897                 }
9898 
9899                 n = export_dependent(opg, exp_str, fmri);
9900                 if (n == NULL) {
9901                         export_property(exp_prop, exp_str, &pgelts,
9902                             SCE_ALL_VALUES);
9903                 } else {
9904                         if (eelts->dependents == NULL)
9905                                 eelts->dependents = n;
9906                         else
9907                                 (void) xmlAddSibling(eelts->dependents,
9908                                     n);
9909                 }
9910         }
9911         if (ret == -1)
9912                 scfdie();
9913 
9914         free(fmri);
9915         free(type);
9916 
9917         scf_iter_destroy(iter);
9918         scf_pg_destroy(opg);
9919 
9920         if (pgelts.propvals != NULL || pgelts.properties != NULL)
9921                 export_pg_elts(&pgelts, SCF_PG_DEPENDENTS, scf_group_framework,
9922                     eelts);
9923 }


10007         return (doc_link);
10008 }
10009 
10010 /*
10011  * Process template information for a service or instances.
10012  */
10013 static void
10014 export_template(scf_propertygroup_t *pg, struct entity_elts *elts,
10015     struct template_elts *telts)
10016 {
10017         size_t mansz = strlen(SCF_PG_TM_MAN_PREFIX);
10018         size_t docsz = strlen(SCF_PG_TM_DOC_PREFIX);
10019         xmlNodePtr child = NULL;
10020 
10021         if (scf_pg_get_name(pg, exp_str, exp_str_sz) < 0)
10022                 scfdie();
10023 
10024         if (strcmp(exp_str, SCF_PG_TM_COMMON_NAME) == 0) {
10025                 telts->common_name = export_tm_loctext(pg, "common_name");
10026                 if (telts->common_name == NULL)
10027                         export_pg(pg, elts, SCE_ALL_VALUES);
10028                 return;
10029         } else if (strcmp(exp_str, SCF_PG_TM_DESCRIPTION) == 0) {
10030                 telts->description = export_tm_loctext(pg, "description");
10031                 if (telts->description == NULL)
10032                         export_pg(pg, elts, SCE_ALL_VALUES);
10033                 return;
10034         }
10035 
10036         if (strncmp(exp_str, SCF_PG_TM_MAN_PREFIX, mansz) == 0) {
10037                 child = export_tm_manpage(pg);
10038         } else if (strncmp(exp_str, SCF_PG_TM_DOC_PREFIX, docsz) == 0) {
10039                 child = export_tm_doc_link(pg);
10040         }
10041 
10042         if (child != NULL) {
10043                 make_node(&telts->documentation, "documentation");
10044                 (void) xmlAddChild(telts->documentation, child);
10045         } else {
10046                 export_pg(pg, elts, SCE_ALL_VALUES);
10047         }
10048 }
10049 
10050 /*
10051  * Process parameter and paramval elements
10052  */
10053 static void
10054 export_parameter(scf_property_t *prop, const char *name,
10055     struct params_elts *elts)
10056 {
10057         xmlNodePtr param;
10058         scf_error_t err = 0;
10059         int ret;
10060 
10061         if (scf_property_get_value(prop, exp_val) == SCF_SUCCESS) {
10062                 if ((param = xmlNewNode(NULL, (xmlChar *)"paramval")) == NULL)
10063                         uu_die(emsg_create_xml);
10064 
10065                 safe_setprop(param, name_attr, name);
10066 


10179                             active_attr) != 0) {
10180                                 err = 1;
10181                                 break;
10182                         }
10183                         continue;
10184                 }
10185                 /*
10186                  * We export the parameter
10187                  */
10188                 export_parameter(exp_prop, p, &eelts[i]);
10189         }
10190 
10191         if (ret == -1)
10192                 scfdie();
10193 
10194         if (err == 1) {
10195                 for (i = 0; i < URI_SCHEME_NUM; ++i)
10196                         xmlFree(type[i]);
10197                 free(type);
10198 
10199                 export_pg(pg, elts, SCE_ALL_VALUES);
10200 
10201                 return;
10202         } else {
10203                 for (i = 0; i < URI_SCHEME_NUM; ++i)
10204                         if (type[i] != NULL) {
10205                                 (void) xmlAddChildList(type[i],
10206                                     eelts[i].paramval);
10207                                 (void) xmlAddChildList(type[i],
10208                                     eelts[i].parameter);
10209                                 (void) xmlAddSibling(event, type[i]);
10210                         }
10211         }
10212         free(type);
10213 
10214         if (elts->notify_params == NULL)
10215                 elts->notify_params = n;
10216         else
10217                 (void) xmlAddSibling(elts->notify_params, n);
10218 }
10219 


10255                         xmlNodePtr rnode, sfnode;
10256 
10257                         rnode = xmlNewNode(NULL, (xmlChar *)"restarter");
10258                         if (rnode == NULL)
10259                                 uu_die(emsg_create_xml);
10260 
10261                         sfnode = xmlNewChild(rnode, NULL,
10262                             (xmlChar *)"service_fmri", NULL);
10263                         if (sfnode == NULL)
10264                                 uu_die(emsg_create_xml);
10265 
10266                         if (set_attr_from_prop(exp_prop, sfnode,
10267                             value_attr) == 0) {
10268                                 elts->restarter = rnode;
10269                                 continue;
10270                         }
10271 
10272                         xmlFreeNode(rnode);
10273                 }
10274 
10275                 export_property(exp_prop, exp_str, &pgelts, SCE_ALL_VALUES);
10276         }
10277         if (ret == -1)
10278                 scfdie();
10279 
10280         if (pgelts.propvals != NULL || pgelts.properties != NULL)
10281                 export_pg_elts(&pgelts, scf_pg_general, scf_group_framework,
10282                     elts);
10283 }
10284 
10285 /*
10286  * Put an instance element for the given instance into selts.
10287  */
10288 static void
10289 export_instance(scf_instance_t *inst, struct entity_elts *selts, int flags)
10290 {
10291         xmlNodePtr n;
10292         boolean_t isdefault;
10293         struct entity_elts elts;
10294         struct template_elts template_elts;
10295         int ret;