1 /*
   2  * CDDL HEADER START
   3  *
   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 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * reeval_callback.c
  29  *    This file is designed to test mapid_reeval_domain(cb_t *)'s
  30  *    callback behavior. It sends requests to libmapid_syscfgd.ksh to
  31  *    change configuration on the test system, and then call
  32  *    mapid_reeval_domain() and check the callback function passed to it
  33  *    is invoked and the new domain value is correct.
  34  *
  35  * Return value:
  36  *    On success, it returns 0; on error, it returns 1.
  37  *
  38  * Usage:
  39  *    ./reeval_callback <setup_cmd> <cleanup_cmd>
  40  *        - setup_cmd: the cmd to change system configuration
  41  *        - cleanup_cmd: the cmd to restore sytem configuration
  42  */
  43 
  44 #include <stdio.h>
  45 #include <nfs/mapid.h>
  46 
  47 #define DNAMEMAX        (NS_MAXCDNAME + 1)
  48 #define LOG(fmt, ...)   if (b_debug) { printf(fmt, __VA_ARGS__); }
  49 #define STRLEN  128
  50 
  51 char domain_from_cb[DNAMEMAX];
  52 char domain_from_lib[DNAMEMAX];
  53 int b_debug;
  54 char tmpdir[STRLEN/2] = { 0 };
  55 
  56 void *cb_get_domain(void *);
  57 int execute_command(char *);
  58 
  59 int
  60 main(int argc, char ** argv)
  61 {
  62         cb_t cb;
  63         FILE *file;
  64         char *p;
  65         char buffer[STRLEN];
  66         int n;
  67         char setup_cmd[STRLEN] = { 0 };
  68         char cleanup_cmd[STRLEN] = { 0 };
  69 
  70         /* check if debug mode is on */
  71         if ((p = getenv("DEBUG")) && atoi(p)) {
  72                 b_debug = 1;
  73         }
  74 
  75         if ((p = getenv("TMPDIR"))) {
  76                 strncpy(tmpdir, p, (STRLEN/2 - 1));
  77         } else {
  78                 strcpy(tmpdir, "/tmp");
  79         }
  80 
  81         if (argc != 3) {
  82                 fprintf(stderr, "Usage: %s <setup_cmd> <cleanup_cmd>\n",
  83                     argv[0]);
  84                 exit(1);
  85         } else {
  86                 strncpy(setup_cmd, argv[1], STRLEN-1);
  87                 strncpy(cleanup_cmd, argv[2], STRLEN-1);
  88         }
  89 
  90         cb.fcn = cb_get_domain;
  91         /* calback function gets called only when there is domain change */
  92         cb.signal = 0;
  93 
  94         /*
  95          * Round 1
  96          */
  97 
  98         mapid_reeval_domain(&cb);
  99 
 100         strncpy(domain_from_lib, mapid_get_domain(), DNAMEMAX);
 101         LOG("Get new domain from lib: %s\n", domain_from_lib);
 102 
 103         if (strcmp(domain_from_lib, domain_from_cb)) {
 104                 fprintf(stderr,
 105                     "domain values mismatch in initialization phase!\n");
 106                 exit(1);
 107         }
 108 
 109         /*
 110          * modify /etc/default/nfs
 111          */
 112         if (execute_command(setup_cmd)) exit(1);
 113 
 114         /*
 115          * Round 2
 116          */
 117 
 118         mapid_reeval_domain(&cb);
 119 
 120         strncpy(domain_from_lib, mapid_get_domain(), DNAMEMAX);
 121         LOG("Get new domain from lib: %s\n", domain_from_lib);
 122 
 123         if (strcmp(domain_from_lib, domain_from_cb)) {
 124                 fprintf(stderr,
 125                 "domain values mismatch after system config changed!\n");
 126                 exit(1);
 127         }
 128 
 129         /*
 130          * Restore /etc/default/nfs
 131          */
 132         if (execute_command(cleanup_cmd)) exit(1);
 133 
 134         exit(0);
 135 }
 136 
 137 void *
 138 cb_get_domain(void * arg) {
 139         char    *new_domain = (char *)arg;
 140 
 141         strncpy(domain_from_cb, new_domain, DNAMEMAX);
 142         LOG("Get new domain from callback function: %s\n", domain_from_cb);
 143         return (0);
 144 }
 145 
 146 int
 147 execute_command(char *cmd) {
 148         char fname[STRLEN];
 149         FILE *file;
 150         char buffer[STRLEN];
 151         int n;
 152         int b_succeed = 0;
 153 
 154         /* create $TMPDIR/<cmd> file to initiate the request */
 155         sprintf(fname, "%s/.libmapid/%s", tmpdir, cmd);
 156 
 157         file = fopen(fname, "w+");
 158         if (!file) {
 159                 fprintf(stderr, "failed to create %s\n", fname);
 160                 perror("fopen");
 161                 return (1);
 162         }
 163         fclose(file);
 164         LOG("Create %s file\n", fname);
 165 
 166         /* check result file */
 167         n = 48;
 168         sprintf(fname, "%s/.libmapid/DONE", tmpdir);
 169         while (n > 0) {
 170                 sleep(5);
 171                 if ((file = fopen(fname, "r"))) {
 172                         /* Got response! Check if it contains "OK" string */
 173                         LOG("Get response in %s file\n", fname);
 174 
 175                         fgets(buffer, STRLEN, file);
 176                         if (strstr(buffer, "OK")) b_succeed = 1;
 177                         fclose(file);
 178 
 179                         break;
 180                 }
 181                 n--;
 182         }
 183 
 184         if (!n) {
 185                 /* time ran out */
 186                 fprintf(stderr, "%s not found...time out! \n", fname);
 187                 return (1);
 188         }
 189 
 190         if (!b_succeed) {
 191                 /* libmapid_syscfgd.ksh failed to handle the request */
 192                 fprintf(stderr,
 193                         "%s failed to modify /etc/default/nfs\n", fname);
 194                 fprintf(stderr, "libmapid_syscfgd log: %s\n", buffer);
 195                 return (1);
 196         }
 197 
 198         /* remove the result file */
 199         unlink(fname);
 200 
 201         return (0);
 202 }