Print this page
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Revert "NEX-5801 Snapshots left over after failed backups"
This reverts commit f182fb95f09036db71fbfc6f0a6b90469b761f21.
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-2911 NDMP logging should use syslog and is too chatty


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



  40 #include <stdio.h>
  41 #include <stdlib.h>
  42 #include <string.h>
  43 #include <strings.h>
  44 #include <cstack.h>
  45 #include <ctype.h>
  46 #include <tlm.h>
  47 #include "tlm_proto.h"
  48 
  49 /*
  50  * Implementation of a list based stack class. The stack only holds
  51  * pointers/references to application objects. The objects are not
  52  * copied and the stack never attempts to dereference or access the
  53  * data objects. Applications should treat cstack_t references as
  54  * opaque handles.
  55  */
  56 
  57 /*
  58  * cstack_new
  59  *


  69         if ((stk = ndmp_malloc(sizeof (cstack_t))) == NULL)
  70                 return (NULL);
  71 
  72         return (stk);
  73 }
  74 
  75 
  76 /*
  77  * cstack_delete
  78  *
  79  * Deallocate the stack. This goes through the list freeing all of the
  80  * cstack nodes but not the data because we don't know how the data was
  81  * allocated. A stack really should be empty before it is deleted.
  82  */
  83 void
  84 cstack_delete(cstack_t *stk)
  85 {
  86         cstack_t *tmp;
  87 
  88         if (stk == NULL) {
  89                 NDMP_LOG(LOG_DEBUG, "cstack_delete: invalid stack");
  90                 return;
  91         }
  92 
  93         while ((tmp = stk->next) != NULL) {
  94                 stk->next = tmp->next;
  95                 NDMP_LOG(LOG_DEBUG, "cstack_delete(element): 0x%p", tmp);
  96                 free(tmp);
  97         }
  98 
  99         NDMP_LOG(LOG_DEBUG, "cstack_delete: 0x%p", stk);
 100         free(stk);
 101 }
 102 
 103 
 104 /*
 105  * cstack_push
 106  *
 107  * Push an element onto the stack. Allocate a new node and assign the
 108  * data and len values. We don't care what about the real values of
 109  * data or len and we never try to access them. The stack head will
 110  * point to the new node.
 111  *
 112  * Returns 0 on success. Otherwise returns -1 to indicate overflow.
 113  */
 114 int
 115 cstack_push(cstack_t *stk, void *data, int len)
 116 {
 117         cstack_t *stk_node;
 118 
 119         if (stk == NULL) {
 120                 NDMP_LOG(LOG_DEBUG, "cstack_push: invalid stack");
 121                 return (-1);
 122         }
 123 
 124         if ((stk_node = ndmp_malloc(sizeof (cstack_t))) == NULL)
 125                 return (-1);
 126 
 127         stk_node->data = data;
 128         stk_node->len = len;
 129         stk_node->next = stk->next;
 130         stk->next = stk_node;
 131 
 132         NDMP_LOG(LOG_DEBUG, "cstack_push(0x%p): 0x%p", stk, stk_node);
 133         return (0);
 134 }
 135 
 136 
 137 /*
 138  * cstack_pop
 139  *
 140  * Pop an element off the stack. Set up the data and len references for
 141  * the caller, advance the stack head and free the popped stack node.
 142  *
 143  * Returns 0 on success. Otherwise returns -1 to indicate underflow.
 144  */
 145 int
 146 cstack_pop(cstack_t *stk, void **data, int *len)
 147 {
 148         cstack_t *stk_node;
 149 
 150         if (stk == NULL) {
 151                 NDMP_LOG(LOG_DEBUG, "cstack_pop: invalid stack");
 152                 return (-1);
 153         }
 154 
 155         if ((stk_node = stk->next) == NULL) {
 156                 NDMP_LOG(LOG_DEBUG, "cstack_pop: underflow");
 157                 return (-1);
 158         }
 159 
 160         if (data)
 161                 *data = stk_node->data;
 162 
 163         if (len)
 164                 *len = stk_node->len;
 165 
 166         stk->next = stk_node->next;
 167         NDMP_LOG(LOG_DEBUG, "cstack_pop(0x%p): 0x%p", stk, stk_node);
 168 
 169         free(stk_node);
 170         return (0);
 171 }
 172 
 173 /*
 174  * cstack_top
 175  *
 176  * Returns the top data element on the stack without removing it.
 177  *
 178  * Returns 0 on success. Otherwise returns -1 to indicate underflow.
 179  */
 180 int
 181 cstack_top(cstack_t *stk, void **data, int *len)
 182 {
 183         if (stk == NULL) {
 184                 NDMP_LOG(LOG_DEBUG, "cstack_pop: invalid stack");
 185                 return (-1);
 186         }
 187 
 188         if (stk->next == NULL) {
 189                 NDMP_LOG(LOG_DEBUG, "cstack_pop: underflow");
 190                 return (-1);
 191         }
 192 
 193         if (data)
 194                 *data = stk->next->data;
 195 
 196         if (len)
 197                 *len = stk->next->len;
 198 
 199         return (0);
 200 }
 201 
 202 /*
 203  * match
 204  *
 205  * Matching rules:
 206  *      c       Any non-special character matches itslef
 207  *      ?       Match any character
 208  *      ab      character 'a' followed by character 'b'
 209  *      S       Any string of non-special characters


 527         return (new_dir_info);
 528 }
 529 
 530 /*
 531  * tlm_new_dir_info
 532  *
 533  * Create a new structure, set fh field to what is specified and the path
 534  * to the concatenation of directory and the component
 535  */
 536 struct full_dir_info *
 537 tlm_new_dir_info(struct  fs_fhandle *fhp, char *dir, char *nm)
 538 {
 539         struct full_dir_info *fdip;
 540 
 541         if (!(fdip = ndmp_malloc(sizeof (struct full_dir_info))))
 542                 return (NULL);
 543 
 544         (void) memcpy(&fdip->fd_dir_fh, fhp, sizeof (fs_fhandle_t));
 545         if (!tlm_cat_path(fdip->fd_dir_name, dir, nm)) {
 546                 free(fdip);
 547                 NDMP_LOG(LOG_DEBUG, "TAPE BACKUP Find> path too long [%s][%s]",
 548                     dir, nm);
 549                 return (NULL);
 550         }
 551         return (fdip);
 552 }
 553 
 554 /*
 555  * sysattr_rdonly
 556  *
 557  * Check if the attribute file is one of the readonly system
 558  * attributes.
 559  */
 560 int
 561 sysattr_rdonly(char *name)
 562 {
 563         return (name && strcmp(name, SYSATTR_RDONLY) == 0);
 564 }
 565 
 566 /*
 567  * sysattr_rw


  20  *        the documentation and/or other materials provided with the
  21  *        distribution.
  22  *
  23  *      - Neither the name of The Storage Networking Industry Association (SNIA)
  24  *        nor the names of its contributors may be used to endorse or promote
  25  *        products derived from this software without specific prior written
  26  *        permission.
  27  *
  28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38  * POSSIBILITY OF SUCH DAMAGE.
  39  */
  40 /* Copyright 2016 Nexenta Systems, Inc. All rights reserved. */
  41 
  42 #include <syslog.h>
  43 #include <stdio.h>
  44 #include <stdlib.h>
  45 #include <string.h>
  46 #include <strings.h>
  47 #include <cstack.h>
  48 #include <ctype.h>
  49 #include <tlm.h>
  50 #include "tlm_proto.h"
  51 
  52 /*
  53  * Implementation of a list based stack class. The stack only holds
  54  * pointers/references to application objects. The objects are not
  55  * copied and the stack never attempts to dereference or access the
  56  * data objects. Applications should treat cstack_t references as
  57  * opaque handles.
  58  */
  59 
  60 /*
  61  * cstack_new
  62  *


  72         if ((stk = ndmp_malloc(sizeof (cstack_t))) == NULL)
  73                 return (NULL);
  74 
  75         return (stk);
  76 }
  77 
  78 
  79 /*
  80  * cstack_delete
  81  *
  82  * Deallocate the stack. This goes through the list freeing all of the
  83  * cstack nodes but not the data because we don't know how the data was
  84  * allocated. A stack really should be empty before it is deleted.
  85  */
  86 void
  87 cstack_delete(cstack_t *stk)
  88 {
  89         cstack_t *tmp;
  90 
  91         if (stk == NULL) {

  92                 return;
  93         }
  94 
  95         while ((tmp = stk->next) != NULL) {
  96                 stk->next = tmp->next;

  97                 free(tmp);
  98         }
  99 

 100         free(stk);
 101 }
 102 
 103 
 104 /*
 105  * cstack_push
 106  *
 107  * Push an element onto the stack. Allocate a new node and assign the
 108  * data and len values. We don't care what about the real values of
 109  * data or len and we never try to access them. The stack head will
 110  * point to the new node.
 111  *
 112  * Returns 0 on success. Otherwise returns -1 to indicate overflow.
 113  */
 114 int
 115 cstack_push(cstack_t *stk, void *data, int len)
 116 {
 117         cstack_t *stk_node;
 118 
 119         if (stk == NULL) {

 120                 return (-1);
 121         }
 122 
 123         if ((stk_node = ndmp_malloc(sizeof (cstack_t))) == NULL)
 124                 return (-1);
 125 
 126         stk_node->data = data;
 127         stk_node->len = len;
 128         stk_node->next = stk->next;
 129         stk->next = stk_node;
 130 

 131         return (0);
 132 }
 133 
 134 
 135 /*
 136  * cstack_pop
 137  *
 138  * Pop an element off the stack. Set up the data and len references for
 139  * the caller, advance the stack head and free the popped stack node.
 140  *
 141  * Returns 0 on success. Otherwise returns -1 to indicate underflow.
 142  */
 143 int
 144 cstack_pop(cstack_t *stk, void **data, int *len)
 145 {
 146         cstack_t *stk_node;
 147 
 148         if (stk == NULL) {

 149                 return (-1);
 150         }
 151 
 152         if ((stk_node = stk->next) == NULL) {

 153                 return (-1);
 154         }
 155 
 156         if (data)
 157                 *data = stk_node->data;
 158 
 159         if (len)
 160                 *len = stk_node->len;
 161 
 162         stk->next = stk_node->next;

 163 
 164         free(stk_node);
 165         return (0);
 166 }
 167 
 168 /*
 169  * cstack_top
 170  *
 171  * Returns the top data element on the stack without removing it.
 172  *
 173  * Returns 0 on success. Otherwise returns -1 to indicate underflow.
 174  */
 175 int
 176 cstack_top(cstack_t *stk, void **data, int *len)
 177 {
 178         if (stk == NULL) {

 179                 return (-1);
 180         }
 181 
 182         if (stk->next == NULL) {

 183                 return (-1);
 184         }
 185 
 186         if (data)
 187                 *data = stk->next->data;
 188 
 189         if (len)
 190                 *len = stk->next->len;
 191 
 192         return (0);
 193 }
 194 
 195 /*
 196  * match
 197  *
 198  * Matching rules:
 199  *      c       Any non-special character matches itslef
 200  *      ?       Match any character
 201  *      ab      character 'a' followed by character 'b'
 202  *      S       Any string of non-special characters


 520         return (new_dir_info);
 521 }
 522 
 523 /*
 524  * tlm_new_dir_info
 525  *
 526  * Create a new structure, set fh field to what is specified and the path
 527  * to the concatenation of directory and the component
 528  */
 529 struct full_dir_info *
 530 tlm_new_dir_info(struct  fs_fhandle *fhp, char *dir, char *nm)
 531 {
 532         struct full_dir_info *fdip;
 533 
 534         if (!(fdip = ndmp_malloc(sizeof (struct full_dir_info))))
 535                 return (NULL);
 536 
 537         (void) memcpy(&fdip->fd_dir_fh, fhp, sizeof (fs_fhandle_t));
 538         if (!tlm_cat_path(fdip->fd_dir_name, dir, nm)) {
 539                 free(fdip);
 540                 syslog(LOG_DEBUG, "TAPE BACKUP Find> path too long [%s][%s]",
 541                     dir, nm);
 542                 return (NULL);
 543         }
 544         return (fdip);
 545 }
 546 
 547 /*
 548  * sysattr_rdonly
 549  *
 550  * Check if the attribute file is one of the readonly system
 551  * attributes.
 552  */
 553 int
 554 sysattr_rdonly(char *name)
 555 {
 556         return (name && strcmp(name, SYSATTR_RDONLY) == 0);
 557 }
 558 
 559 /*
 560  * sysattr_rw