Print this page
3347 zonecfg(1M) is confused about selection
4956 zonecfg won't use a valid pager


   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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.

  25  */
  26 
  27 /*
  28  * zonecfg is a lex/yacc based command interpreter used to manage zone
  29  * configurations.  The lexer (see zonecfg_lex.l) builds up tokens, which
  30  * the grammar (see zonecfg_grammar.y) builds up into commands, some of
  31  * which takes resources and/or properties as arguments.  See the block
  32  * comments near the end of zonecfg_grammar.y for how the data structures
  33  * which keep track of these resources and properties are built up.
  34  *
  35  * The resource/property data structures are inserted into a command
  36  * structure (see zonecfg.h), which also keeps track of command names,
  37  * miscellaneous arguments, and function handlers.  The grammar selects
  38  * the appropriate function handler, each of which takes a pointer to a
  39  * command structure as its sole argument, and invokes it.  The grammar
  40  * itself is "entered" (a la the Matrix) by yyparse(), which is called
  41  * from read_input(), our main driving function.  That in turn is called
  42  * by one of do_interactive(), cmd_file() or one_command_at_a_time(), each
  43  * of which is called from main() depending on how the program was invoked.
  44  *


 914  */
 915 
 916 void
 917 usage(boolean_t verbose, uint_t flags)
 918 {
 919         FILE *fp = verbose ? stdout : stderr;
 920         FILE *newfp;
 921         boolean_t need_to_close = B_FALSE;
 922         char *pager, *space;
 923         int i;
 924         struct stat statbuf;
 925 
 926         /* don't page error output */
 927         if (verbose && interactive_mode) {
 928                 if ((pager = getenv("PAGER")) == NULL)
 929                         pager = PAGER;
 930 
 931                 space = strchr(pager, ' ');
 932                 if (space)
 933                         *space = '\0';
 934                 if (stat(pager, &statbuf) == 0) {



 935                         if (space)
 936                                 *space = ' ';
 937                         if ((newfp = popen(pager, "w")) != NULL) {



 938                                 need_to_close = B_TRUE;
 939                                 fp = newfp;
 940                         }
 941                 } else {
 942                         zerr(gettext("PAGER %s does not exist (%s)."),
 943                             pager, strerror(errno));
 944                 }
 945         }
 946 
 947         if (flags & HELP_META) {
 948                 (void) fprintf(fp, gettext("More help is available for the "
 949                     "following:\n"));
 950                 (void) fprintf(fp, "\n\tcommands ('%s commands')\n",
 951                     cmd_to_str(CMD_HELP));
 952                 (void) fprintf(fp, "\tsyntax ('%s syntax')\n",
 953                     cmd_to_str(CMD_HELP));
 954                 (void) fprintf(fp, "\tusage ('%s usage')\n\n",
 955                     cmd_to_str(CMD_HELP));
 956                 (void) fprintf(fp, gettext("You may also obtain help on any "
 957                     "command by typing '%s <command-name>.'\n"),
 958                     cmd_to_str(CMD_HELP));
 959         }
 960         if (flags & HELP_RES_SCOPE) {
 961                 switch (resource_scope) {
 962                 case RT_FS:
 963                         (void) fprintf(fp, gettext("The '%s' resource scope is "


1256                     pt_to_str(PT_PHYSICAL), pt_to_str(PT_DEFROUTER));
1257                 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE),
1258                     pt_to_str(PT_MATCH));
1259                 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
1260                     pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
1261                 (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR),
1262                     pt_to_str(PT_NAME), pt_to_str(PT_TYPE),
1263                     pt_to_str(PT_VALUE));
1264                 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DATASET),
1265                     pt_to_str(PT_NAME));
1266                 (void) fprintf(fp, "\t%s\t%s, %s\n", rt_to_str(RT_DCPU),
1267                     pt_to_str(PT_NCPUS), pt_to_str(PT_IMPORTANCE));
1268                 (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_PCAP),
1269                     pt_to_str(PT_NCPUS));
1270                 (void) fprintf(fp, "\t%s\t%s, %s, %s\n", rt_to_str(RT_MCAP),
1271                     pt_to_str(PT_PHYSICAL), pt_to_str(PT_SWAP),
1272                     pt_to_str(PT_LOCKED));
1273                 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
1274                     pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
1275         }
1276         if (need_to_close)
1277                 (void) pclose(fp);









1278 }
1279 
1280 static void
1281 zone_perror(char *prefix, int err, boolean_t set_saw)
1282 {
1283         zerr("%s: %s", prefix, zonecfg_strerror(err));
1284         if (set_saw)
1285                 saw_error = B_TRUE;
1286 }
1287 
1288 /*
1289  * zone_perror() expects a single string, but for remove and select
1290  * we have both the command and the resource type, so this wrapper
1291  * function serves the same purpose in a slightly different way.
1292  */
1293 
1294 static void
1295 z_cmd_rt_perror(int cmd_num, int res_num, int err, boolean_t set_saw)
1296 {
1297         zerr("%s %s: %s", cmd_to_str(cmd_num), rt_to_str(res_num),


5345         boolean_t need_to_close = B_FALSE;
5346         char *pager, *space;
5347         int type;
5348         int res1, res2;
5349         uint64_t swap_limit;
5350         uint64_t locked_limit;
5351         struct stat statbuf;
5352 
5353         assert(cmd != NULL);
5354 
5355         if (initialize(B_TRUE) != Z_OK)
5356                 return;
5357 
5358         /* don't page error output */
5359         if (interactive_mode) {
5360                 if ((pager = getenv("PAGER")) == NULL)
5361                         pager = PAGER;
5362                 space = strchr(pager, ' ');
5363                 if (space)
5364                         *space = '\0';
5365                 if (stat(pager, &statbuf) == 0) {



5366                         if (space)
5367                                 *space = ' ';
5368                         if ((fp = popen(pager, "w")) != NULL)
5369                                 need_to_close = B_TRUE;
5370                         else
5371                                 fp = stdout;
5372                 } else {
5373                         zerr(gettext("PAGER %s does not exist (%s)."),
5374                             pager, strerror(errno));


5375                 }

5376 
5377                 setbuf(fp, NULL);
5378         }
5379 
5380         if (!global_scope) {
5381                 switch (resource_scope) {
5382                 case RT_FS:
5383                         output_fs(fp, &in_progress_fstab);
5384                         break;
5385                 case RT_NET:
5386                         output_net(fp, &in_progress_nwiftab);
5387                         break;
5388                 case RT_DEVICE:
5389                         output_dev(fp, &in_progress_devtab);
5390                         break;
5391                 case RT_RCTL:
5392                         output_rctl(fp, &in_progress_rctltab);
5393                         break;
5394                 case RT_ATTR:
5395                         output_attr(fp, &in_progress_attrtab);


5544                 info_pcap(fp);
5545                 break;
5546         case RT_MCAP:
5547                 info_mcap(handle, fp);
5548                 break;
5549         case RT_HOSTID:
5550                 info_hostid(handle, fp);
5551                 break;
5552         case RT_ADMIN:
5553                 info_auth(handle, fp, cmd);
5554                 break;
5555         case RT_FS_ALLOWED:
5556                 info_fs_allowed(handle, fp);
5557                 break;
5558         default:
5559                 zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
5560                     B_TRUE);
5561         }
5562 
5563 cleanup:
5564         if (need_to_close)
5565                 (void) pclose(fp);









5566 }
5567 
5568 /*
5569  * Helper function for verify-- checks that a required string property
5570  * exists.
5571  */
5572 static void
5573 check_reqd_prop(char *attr, int rt, int pt, int *ret_val)
5574 {
5575         if (strlen(attr) == 0) {
5576                 zerr(gettext("%s: %s not specified"), rt_to_str(rt),
5577                     pt_to_str(pt));
5578                 saw_error = B_TRUE;
5579                 if (*ret_val == Z_OK)
5580                         *ret_val = Z_REQD_PROPERTY_MISSING;
5581         }
5582 }
5583 
5584 static int
5585 do_subproc(char *cmdbuf)




   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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2014 Gary Mills
  26  */
  27 
  28 /*
  29  * zonecfg is a lex/yacc based command interpreter used to manage zone
  30  * configurations.  The lexer (see zonecfg_lex.l) builds up tokens, which
  31  * the grammar (see zonecfg_grammar.y) builds up into commands, some of
  32  * which takes resources and/or properties as arguments.  See the block
  33  * comments near the end of zonecfg_grammar.y for how the data structures
  34  * which keep track of these resources and properties are built up.
  35  *
  36  * The resource/property data structures are inserted into a command
  37  * structure (see zonecfg.h), which also keeps track of command names,
  38  * miscellaneous arguments, and function handlers.  The grammar selects
  39  * the appropriate function handler, each of which takes a pointer to a
  40  * command structure as its sole argument, and invokes it.  The grammar
  41  * itself is "entered" (a la the Matrix) by yyparse(), which is called
  42  * from read_input(), our main driving function.  That in turn is called
  43  * by one of do_interactive(), cmd_file() or one_command_at_a_time(), each
  44  * of which is called from main() depending on how the program was invoked.
  45  *


 915  */
 916 
 917 void
 918 usage(boolean_t verbose, uint_t flags)
 919 {
 920         FILE *fp = verbose ? stdout : stderr;
 921         FILE *newfp;
 922         boolean_t need_to_close = B_FALSE;
 923         char *pager, *space;
 924         int i;
 925         struct stat statbuf;
 926 
 927         /* don't page error output */
 928         if (verbose && interactive_mode) {
 929                 if ((pager = getenv("PAGER")) == NULL)
 930                         pager = PAGER;
 931 
 932                 space = strchr(pager, ' ');
 933                 if (space)
 934                         *space = '\0';
 935                 if (*pager == '/' && stat(pager, &statbuf) != 0) {
 936                         zerr(gettext("PAGER %s does not exist (%s)."),
 937                             pager, strerror(errno));
 938                 } else {
 939                         if (space)
 940                                 *space = ' ';
 941                         if ((newfp = popen(pager, "w")) == NULL) {
 942                                 zerr(gettext("PAGER %s open failed (%s)."),
 943                                     pager, strerror(errno));
 944                         } else {
 945                                 need_to_close = B_TRUE;
 946                                 fp = newfp;
 947                         }



 948                 }
 949         }
 950 
 951         if (flags & HELP_META) {
 952                 (void) fprintf(fp, gettext("More help is available for the "
 953                     "following:\n"));
 954                 (void) fprintf(fp, "\n\tcommands ('%s commands')\n",
 955                     cmd_to_str(CMD_HELP));
 956                 (void) fprintf(fp, "\tsyntax ('%s syntax')\n",
 957                     cmd_to_str(CMD_HELP));
 958                 (void) fprintf(fp, "\tusage ('%s usage')\n\n",
 959                     cmd_to_str(CMD_HELP));
 960                 (void) fprintf(fp, gettext("You may also obtain help on any "
 961                     "command by typing '%s <command-name>.'\n"),
 962                     cmd_to_str(CMD_HELP));
 963         }
 964         if (flags & HELP_RES_SCOPE) {
 965                 switch (resource_scope) {
 966                 case RT_FS:
 967                         (void) fprintf(fp, gettext("The '%s' resource scope is "


1260                     pt_to_str(PT_PHYSICAL), pt_to_str(PT_DEFROUTER));
1261                 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE),
1262                     pt_to_str(PT_MATCH));
1263                 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
1264                     pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
1265                 (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR),
1266                     pt_to_str(PT_NAME), pt_to_str(PT_TYPE),
1267                     pt_to_str(PT_VALUE));
1268                 (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DATASET),
1269                     pt_to_str(PT_NAME));
1270                 (void) fprintf(fp, "\t%s\t%s, %s\n", rt_to_str(RT_DCPU),
1271                     pt_to_str(PT_NCPUS), pt_to_str(PT_IMPORTANCE));
1272                 (void) fprintf(fp, "\t%s\t%s\n", rt_to_str(RT_PCAP),
1273                     pt_to_str(PT_NCPUS));
1274                 (void) fprintf(fp, "\t%s\t%s, %s, %s\n", rt_to_str(RT_MCAP),
1275                     pt_to_str(PT_PHYSICAL), pt_to_str(PT_SWAP),
1276                     pt_to_str(PT_LOCKED));
1277                 (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
1278                     pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
1279         }
1280         if (need_to_close) {
1281                 int status;
1282 
1283                 status = pclose(fp);
1284                 if (status == -1)
1285                         zerr(gettext("PAGER %s close failed (%s)."),
1286                             pager, strerror(errno));
1287                 else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
1288                         zerr(gettext("PAGER %s exit code: %d."),
1289                             pager, WEXITSTATUS(status));
1290         }
1291 }
1292 
1293 static void
1294 zone_perror(char *prefix, int err, boolean_t set_saw)
1295 {
1296         zerr("%s: %s", prefix, zonecfg_strerror(err));
1297         if (set_saw)
1298                 saw_error = B_TRUE;
1299 }
1300 
1301 /*
1302  * zone_perror() expects a single string, but for remove and select
1303  * we have both the command and the resource type, so this wrapper
1304  * function serves the same purpose in a slightly different way.
1305  */
1306 
1307 static void
1308 z_cmd_rt_perror(int cmd_num, int res_num, int err, boolean_t set_saw)
1309 {
1310         zerr("%s %s: %s", cmd_to_str(cmd_num), rt_to_str(res_num),


5358         boolean_t need_to_close = B_FALSE;
5359         char *pager, *space;
5360         int type;
5361         int res1, res2;
5362         uint64_t swap_limit;
5363         uint64_t locked_limit;
5364         struct stat statbuf;
5365 
5366         assert(cmd != NULL);
5367 
5368         if (initialize(B_TRUE) != Z_OK)
5369                 return;
5370 
5371         /* don't page error output */
5372         if (interactive_mode) {
5373                 if ((pager = getenv("PAGER")) == NULL)
5374                         pager = PAGER;
5375                 space = strchr(pager, ' ');
5376                 if (space)
5377                         *space = '\0';
5378                 if (*pager == '/' && stat(pager, &statbuf) != 0) {
5379                         zerr(gettext("PAGER %s does not exist (%s)."),
5380                             pager, strerror(errno));
5381                 } else {
5382                         if (space)
5383                                 *space = ' ';
5384                         if ((fp = popen(pager, "w")) == NULL) {


5385                                 fp = stdout;
5386                                 zerr(gettext("PAGER %s open failed (%s)."),

5387                                     pager, strerror(errno));
5388                         } else {
5389                                 need_to_close = B_TRUE;
5390                         }
5391                 }
5392 
5393                 setbuf(fp, NULL);
5394         }
5395 
5396         if (!global_scope) {
5397                 switch (resource_scope) {
5398                 case RT_FS:
5399                         output_fs(fp, &in_progress_fstab);
5400                         break;
5401                 case RT_NET:
5402                         output_net(fp, &in_progress_nwiftab);
5403                         break;
5404                 case RT_DEVICE:
5405                         output_dev(fp, &in_progress_devtab);
5406                         break;
5407                 case RT_RCTL:
5408                         output_rctl(fp, &in_progress_rctltab);
5409                         break;
5410                 case RT_ATTR:
5411                         output_attr(fp, &in_progress_attrtab);


5560                 info_pcap(fp);
5561                 break;
5562         case RT_MCAP:
5563                 info_mcap(handle, fp);
5564                 break;
5565         case RT_HOSTID:
5566                 info_hostid(handle, fp);
5567                 break;
5568         case RT_ADMIN:
5569                 info_auth(handle, fp, cmd);
5570                 break;
5571         case RT_FS_ALLOWED:
5572                 info_fs_allowed(handle, fp);
5573                 break;
5574         default:
5575                 zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
5576                     B_TRUE);
5577         }
5578 
5579 cleanup:
5580         if (need_to_close) {
5581                 int status;
5582 
5583                 status = pclose(fp);
5584                 if (status == -1)
5585                         zerr(gettext("PAGER %s close failed (%s)."),
5586                             pager, strerror(errno));
5587                 else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
5588                         zerr(gettext("PAGER %s exit code: %d."),
5589                             pager, WEXITSTATUS(status));
5590         }
5591 }
5592 
5593 /*
5594  * Helper function for verify-- checks that a required string property
5595  * exists.
5596  */
5597 static void
5598 check_reqd_prop(char *attr, int rt, int pt, int *ret_val)
5599 {
5600         if (strlen(attr) == 0) {
5601                 zerr(gettext("%s: %s not specified"), rt_to_str(rt),
5602                     pt_to_str(pt));
5603                 saw_error = B_TRUE;
5604                 if (*ret_val == Z_OK)
5605                         *ret_val = Z_REQD_PROPERTY_MISSING;
5606         }
5607 }
5608 
5609 static int
5610 do_subproc(char *cmdbuf)