Print this page
NEX-9532 NDMP: readdir errors when file/directory has special characters
Reviewed by: Peer Dampmann <peer.dampmann@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-2911 NDMP logging should use syslog and is too chatty


  19  *        the documentation and/or other materials provided with the
  20  *        distribution.
  21  *
  22  *      - Neither the name of The Storage Networking Industry Association (SNIA)
  23  *        nor the names of its contributors may be used to endorse or promote
  24  *        products derived from this software without specific prior written
  25  *        permission.
  26  *
  27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37  * POSSIBILITY OF SUCH DAMAGE.
  38  */

  39 
  40 /* This file contains all the door server code */
  41 

  42 #include <door.h>
  43 #include <alloca.h>
  44 #include <errno.h>
  45 #include <note.h>
  46 #include <libintl.h>
  47 #include <ndmpd_door.h>
  48 #include "ndmpd.h"
  49 
  50 /* static variables */
  51 static int      ndmp_door_fildes = -1;
  52 static mutex_t  ndmp_doorsrv_mutex;
  53 
  54 /* static routines */
  55 static void ndmp_door_server(void *cookie, char *ptr, size_t size,
  56     door_desc_t *dp, uint_t n_desc);
  57 
  58 /*
  59  * Statistics used in ndmpstat command
  60  */
  61 ndmp_stat_t ndstat;
  62 
  63 int
  64 ndmp_door_init(void)
  65 {
  66         int fd;
  67 
  68         (void) mutex_lock(&ndmp_doorsrv_mutex);
  69 
  70         if (ndmp_door_fildes != -1) {
  71                 NDMP_LOG(LOG_DEBUG,
  72                     "ndmp_door_init: ndmpd service is already running.");
  73                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
  74                 return (0);
  75         }
  76 
  77         if ((ndmp_door_fildes = door_create(ndmp_door_server,
  78             NULL, DOOR_UNREF)) < 0) {
  79                 NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Could not create door.");
  80                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
  81                 return (-1);
  82         }
  83 
  84         (void) unlink(NDMP_DOOR_SVC);
  85 
  86         if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
  87                 NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Can't create %s: %m.",
  88                     NDMP_DOOR_SVC);
  89                 (void) door_revoke(ndmp_door_fildes);
  90                 ndmp_door_fildes = -1;
  91                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
  92                 return (-1);
  93         }
  94 
  95         (void) close(fd);
  96         (void) fdetach(NDMP_DOOR_SVC);
  97 
  98         if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) {
  99                 NDMP_LOG(LOG_DEBUG, "ndmp_door_init: fattach failed %m");
 100                 (void) door_revoke(ndmp_door_fildes);
 101                 ndmp_door_fildes = -1;
 102                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
 103                 return (-1);
 104         }
 105 
 106         NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
 107         (void) mutex_unlock(&ndmp_doorsrv_mutex);
 108         return (0);
 109 }
 110 
 111 void
 112 ndmp_door_fini(void)
 113 {
 114         (void) mutex_lock(&ndmp_doorsrv_mutex);
 115 
 116         if (ndmp_door_fildes != -1) {
 117                 (void) fdetach(NDMP_DOOR_SVC);
 118                 (void) door_revoke(ndmp_door_fildes);
 119                 ndmp_door_fildes = -1;
 120         }
 121 
 122         (void) mutex_unlock(&ndmp_doorsrv_mutex);
 123 }
 124 
 125 boolean_t
 126 ndmp_door_check(void)
 127 {
 128         door_info_t info;
 129         int door;
 130 
 131         if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0)
 132                 return (0);
 133 
 134         if (door_info(door, &info) < 0) {
 135                 (void) close(door);
 136                 return (0);
 137         }
 138 
 139         if (info.di_target > 0) {
 140                 NDMP_LOG(LOG_ERR,
 141                     "Service already running: pid %ld", info.di_target);
 142                 (void) close(door);
 143                 return (1);
 144         }
 145 
 146         (void) close(door);
 147         return (0);
 148 }
 149 
 150 /* door server */
 151 /*ARGSUSED*/
 152 void
 153 ndmp_door_server(void *cookie, char *ptr, size_t size,
 154     door_desc_t *dp, uint_t n_desc)
 155 {
 156         NOTE(ARGUNUSED(cookie,dp,n_desc))
 157         int req_type;
 158         char *buf;
 159         int buflen;
 160         unsigned int used;
 161         ndmp_door_ctx_t *dec_ctx;
 162         ndmp_door_ctx_t *enc_ctx;
 163         unsigned int dec_status;
 164         unsigned int enc_status;
 165 
 166         dec_ctx = ndmp_door_decode_start(ptr, size);
 167         if (dec_ctx == 0)
 168                 return;
 169 
 170         req_type = ndmp_door_get_uint32(dec_ctx);
 171         buflen = NDMP_DOOR_SIZE;
 172 
 173         if ((buf = alloca(buflen)) == NULL) {
 174                 NDMP_LOG(LOG_DEBUG, "Out of memory.");
 175                 (void) ndmp_door_decode_finish(dec_ctx);
 176                 return;
 177         }
 178 
 179         enc_ctx = ndmp_door_encode_start(buf, buflen);
 180         if (enc_ctx == 0) {
 181                 (void) ndmp_door_decode_finish(dec_ctx);
 182                 return;
 183         }
 184 
 185         if (req_type != NDMP_GET_STAT)
 186                 NDMP_LOG(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type);
 187 
 188         switch (req_type) {
 189         case NDMP_GET_DOOR_STATUS: {
 190                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 191                 break;
 192                 }
 193         case NDMP_DEVICES_GET_INFO: {
 194                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 195                 ndmpd_get_devs(enc_ctx);
 196                 break;
 197                 }
 198         case NDMP_SHOW: {
 199                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 200                 ndmp_connect_list_get(enc_ctx);
 201                 break;
 202                 }
 203         case NDMP_TERMINATE_SESSION_ID: {
 204                 int status, id;
 205                 id = ndmp_door_get_int32(dec_ctx);
 206                 status = ndmpd_connect_kill_id(id);


 212                             NDMP_DOOR_SRV_SUCCESS);
 213                 ndmp_door_put_int32(enc_ctx, status);
 214                 break;
 215                 }
 216 
 217         case NDMP_GET_STAT:
 218                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 219                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_trun);
 220                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_twait);
 221                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_nbk);
 222                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_nrs);
 223                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_rfile);
 224                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_wfile);
 225                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_rdisk);
 226                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_wdisk);
 227                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_rtape);
 228                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_wtape);
 229                 break;
 230 
 231         default:
 232                 NDMP_LOG(LOG_DEBUG,
 233                     "ndmp_door_server: Invalid request type 0x%x", req_type);
 234                 goto decode_error;
 235         }
 236 
 237         if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0)
 238                 goto decode_error;
 239 
 240         if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0)
 241                 goto encode_error;
 242 
 243         (void) door_return(buf, used, NULL, 0);
 244 
 245         return;
 246 
 247 decode_error:
 248         ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
 249         ndmp_door_put_uint32(enc_ctx, dec_status);
 250         (void) ndmp_door_encode_finish(enc_ctx, &used);
 251         (void) door_return(buf, used, NULL, 0);
 252         return;


  19  *        the documentation and/or other materials provided with the
  20  *        distribution.
  21  *
  22  *      - Neither the name of The Storage Networking Industry Association (SNIA)
  23  *        nor the names of its contributors may be used to endorse or promote
  24  *        products derived from this software without specific prior written
  25  *        permission.
  26  *
  27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37  * POSSIBILITY OF SUCH DAMAGE.
  38  */
  39 /* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
  40 
  41 /* This file contains all the door server code */
  42 
  43 #include <syslog.h>
  44 #include <door.h>
  45 #include <alloca.h>
  46 #include <errno.h>
  47 #include <note.h>
  48 #include <libintl.h>
  49 #include <ndmpd_door.h>
  50 #include "ndmpd.h"
  51 
  52 /* static variables */
  53 static int      ndmp_door_fildes = -1;
  54 static mutex_t  ndmp_doorsrv_mutex;
  55 
  56 /* static routines */
  57 static void ndmp_door_server(void *cookie, char *ptr, size_t size,
  58     door_desc_t *dp, uint_t n_desc);
  59 
  60 /*
  61  * Statistics used in ndmpstat command
  62  */
  63 ndmp_stat_t ndstat;
  64 
  65 int
  66 ndmp_door_init(void)
  67 {
  68         int fd;
  69 
  70         (void) mutex_lock(&ndmp_doorsrv_mutex);
  71 
  72         if (ndmp_door_fildes != -1) {
  73                 syslog(LOG_ERR,
  74                     "ndmp_door_init: ndmpd service is already running.");
  75                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
  76                 return (0);
  77         }
  78 
  79         if ((ndmp_door_fildes = door_create(ndmp_door_server,
  80             NULL, DOOR_UNREF)) < 0) {
  81                 syslog(LOG_ERR, "ndmp_door_init: Could not create door.");
  82                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
  83                 return (-1);
  84         }
  85 
  86         (void) unlink(NDMP_DOOR_SVC);
  87 
  88         if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
  89                 syslog(LOG_ERR, "ndmp_door_init: Can't create %s: %m.",
  90                     NDMP_DOOR_SVC);
  91                 (void) door_revoke(ndmp_door_fildes);
  92                 ndmp_door_fildes = -1;
  93                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
  94                 return (-1);
  95         }
  96 
  97         (void) close(fd);
  98         (void) fdetach(NDMP_DOOR_SVC);
  99 
 100         if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) {
 101                 syslog(LOG_ERR, "ndmp_door_init: fattach failed %m");
 102                 (void) door_revoke(ndmp_door_fildes);
 103                 ndmp_door_fildes = -1;
 104                 (void) mutex_unlock(&ndmp_doorsrv_mutex);
 105                 return (-1);
 106         }
 107 
 108         syslog(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
 109         (void) mutex_unlock(&ndmp_doorsrv_mutex);
 110         return (0);
 111 }
 112 
 113 void
 114 ndmp_door_fini(void)
 115 {
 116         (void) mutex_lock(&ndmp_doorsrv_mutex);
 117 
 118         if (ndmp_door_fildes != -1) {
 119                 (void) fdetach(NDMP_DOOR_SVC);
 120                 (void) door_revoke(ndmp_door_fildes);
 121                 ndmp_door_fildes = -1;
 122         }
 123 
 124         (void) mutex_unlock(&ndmp_doorsrv_mutex);
 125 }
 126 
 127 boolean_t
 128 ndmp_door_check(void)
 129 {
 130         door_info_t info;
 131         int door;
 132 
 133         if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0)
 134                 return (0);
 135 
 136         if (door_info(door, &info) < 0) {
 137                 (void) close(door);
 138                 return (0);
 139         }
 140 
 141         if (info.di_target > 0) {
 142                 syslog(LOG_ERR,
 143                     "Service already running: pid %ld", info.di_target);
 144                 (void) close(door);
 145                 return (1);
 146         }
 147 
 148         (void) close(door);
 149         return (0);
 150 }
 151 
 152 /* door server */
 153 /*ARGSUSED*/
 154 void
 155 ndmp_door_server(void *cookie, char *ptr, size_t size,
 156     door_desc_t *dp, uint_t n_desc)
 157 {
 158         NOTE(ARGUNUSED(cookie,dp,n_desc))
 159         int req_type;
 160         char *buf;
 161         int buflen;
 162         unsigned int used;
 163         ndmp_door_ctx_t *dec_ctx;
 164         ndmp_door_ctx_t *enc_ctx;
 165         unsigned int dec_status = EINVAL;
 166         unsigned int enc_status = EINVAL;
 167 
 168         dec_ctx = ndmp_door_decode_start(ptr, size);
 169         if (dec_ctx == 0)
 170                 return;
 171 
 172         req_type = ndmp_door_get_uint32(dec_ctx);
 173         buflen = NDMP_DOOR_SIZE;
 174 
 175         if ((buf = alloca(buflen)) == NULL) {
 176                 syslog(LOG_ERR, "Out of memory.");
 177                 (void) ndmp_door_decode_finish(dec_ctx);
 178                 return;
 179         }
 180 
 181         enc_ctx = ndmp_door_encode_start(buf, buflen);
 182         if (enc_ctx == 0) {
 183                 (void) ndmp_door_decode_finish(dec_ctx);
 184                 return;
 185         }
 186 
 187         if (req_type != NDMP_GET_STAT)
 188                 syslog(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type);
 189 
 190         switch (req_type) {
 191         case NDMP_GET_DOOR_STATUS: {
 192                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 193                 break;
 194                 }
 195         case NDMP_DEVICES_GET_INFO: {
 196                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 197                 ndmpd_get_devs(enc_ctx);
 198                 break;
 199                 }
 200         case NDMP_SHOW: {
 201                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 202                 ndmp_connect_list_get(enc_ctx);
 203                 break;
 204                 }
 205         case NDMP_TERMINATE_SESSION_ID: {
 206                 int status, id;
 207                 id = ndmp_door_get_int32(dec_ctx);
 208                 status = ndmpd_connect_kill_id(id);


 214                             NDMP_DOOR_SRV_SUCCESS);
 215                 ndmp_door_put_int32(enc_ctx, status);
 216                 break;
 217                 }
 218 
 219         case NDMP_GET_STAT:
 220                 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
 221                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_trun);
 222                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_twait);
 223                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_nbk);
 224                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_nrs);
 225                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_rfile);
 226                 ndmp_door_put_uint32(enc_ctx, ndstat.ns_wfile);
 227                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_rdisk);
 228                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_wdisk);
 229                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_rtape);
 230                 ndmp_door_put_uint64(enc_ctx, ndstat.ns_wtape);
 231                 break;
 232 
 233         default:
 234                 syslog(LOG_ERR,
 235                     "ndmp_door_server: Invalid request type 0x%x", req_type);
 236                 goto decode_error;
 237         }
 238 
 239         if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0)
 240                 goto decode_error;
 241 
 242         if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0)
 243                 goto encode_error;
 244 
 245         (void) door_return(buf, used, NULL, 0);
 246 
 247         return;
 248 
 249 decode_error:
 250         ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
 251         ndmp_door_put_uint32(enc_ctx, dec_status);
 252         (void) ndmp_door_encode_finish(enc_ctx, &used);
 253         (void) door_return(buf, used, NULL, 0);
 254         return;