LCOV - code coverage report
Current view: top level - drivers - tapdisk-vbd.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 4 75.0 %
Date: 2025-03-10 18:15:27 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2016, Citrix Systems, Inc.
       3                 :            :  *
       4                 :            :  * All rights reserved.
       5                 :            :  *
       6                 :            :  * Redistribution and use in source and binary forms, with or without
       7                 :            :  * modification, are permitted provided that the following conditions are met:
       8                 :            :  * 
       9                 :            :  *  1. Redistributions of source code must retain the above copyright
      10                 :            :  *     notice, this list of conditions and the following disclaimer.
      11                 :            :  *  2. Redistributions in binary form must reproduce the above copyright
      12                 :            :  *     notice, this list of conditions and the following disclaimer in the
      13                 :            :  *     documentation and/or other materials provided with the distribution.
      14                 :            :  *  3. Neither the name of the copyright holder nor the names of its 
      15                 :            :  *     contributors may be used to endorse or promote products derived from 
      16                 :            :  *     this software without specific prior written permission.
      17                 :            :  *
      18                 :            :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      19                 :            :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      20                 :            :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      21                 :            :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
      22                 :            :  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      23                 :            :  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      24                 :            :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      25                 :            :  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      26                 :            :  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      27                 :            :  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      28                 :            :  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29                 :            :  */
      30                 :            : 
      31                 :            : #ifndef _TAPDISK_VBD_H_
      32                 :            : #define _TAPDISK_VBD_H_
      33                 :            : 
      34                 :            : #include <sys/time.h>
      35                 :            : 
      36                 :            : #include "tapdisk.h"
      37                 :            : #include "scheduler.h"
      38                 :            : #include "tapdisk-image.h"
      39                 :            : #include "tapdisk-blktap.h"
      40                 :            : #include "td-blkif.h"
      41                 :            : 
      42                 :            : #define TD_VBD_REQUEST_TIMEOUT      120
      43                 :            : #define TD_VBD_MAX_RETRIES          100
      44                 :            : #define TD_VBD_RETRY_INTERVAL       1
      45                 :            : 
      46                 :            : /*
      47                 :            :  * VBD states
      48                 :            :  */
      49                 :            : #define TD_VBD_DEAD                 0x0001
      50                 :            : #define TD_VBD_CLOSED               0x0002
      51                 :            : #define TD_VBD_QUIESCE_REQUESTED    0x0004
      52                 :            : #define TD_VBD_QUIESCED             0x0008
      53                 :            : #define TD_VBD_PAUSE_REQUESTED      0x0010
      54                 :            : #define TD_VBD_PAUSED               0x0020
      55                 :            : #define TD_VBD_SHUTDOWN_REQUESTED   0x0040
      56                 :            : #define TD_VBD_LOCKING              0x0080
      57                 :            : #define TD_VBD_LOG_DROPPED          0x0100
      58                 :            : #define TD_VBD_RESUME_FAILED        0x0200
      59                 :            : 
      60                 :            : #define TD_VBD_SECONDARY_DISABLED   0
      61                 :            : #define TD_VBD_SECONDARY_MIRROR     1
      62                 :            : #define TD_VBD_SECONDARY_STANDBY    2
      63                 :            : 
      64                 :            : struct td_nbdserver;
      65                 :            : 
      66                 :            : struct td_vbd_rrd {
      67                 :            : 
      68                 :            :     struct shm shm;
      69                 :            : 
      70                 :            :     /*
      71                 :            :      * Previous value of td_vbd_handle.errors. We maintain this in order to
      72                 :            :      * tell whether we need to update the RRD.
      73                 :            :      */
      74                 :            :     uint64_t last_errors;
      75                 :            : 
      76                 :            :         time_t last;
      77                 :            : };
      78                 :            : 
      79                 :            : struct td_vbd_handle {
      80                 :            :         /**
      81                 :            :          * type:/path/to/file
      82                 :            :          */
      83                 :            :         char                       *name;
      84                 :            : 
      85                 :            :         td_blktap_t                *tap;
      86                 :            : 
      87                 :            :         td_uuid_t                   uuid;
      88                 :            : 
      89                 :            :         /**
      90                 :            :          * shared rings
      91                 :            :          */
      92                 :            :         struct list_head           rings;
      93                 :            : 
      94                 :            :         /**
      95                 :            :          * List of rings that contain pending requests but a disconnection was
      96                 :            :          * issued. We need to maintain these rings until all their pending requests
      97                 :            :          * complete. When the last request completes, the ring is destroyed and
      98                 :            :          * removed from this list.
      99                 :            :          */
     100                 :            :         struct list_head            dead_rings;
     101                 :            : 
     102                 :            :         td_flag_t                   flags;
     103                 :            : 
     104                 :            :         /**
     105                 :            :          * VBD state (TD_VBD_XXX, excluding SECONDARY and request-related)
     106                 :            :          */
     107                 :            :         td_flag_t                   state;
     108                 :            : 
     109                 :            :         /**
     110                 :            :          * List of images: the leaf is at the head, the tree root is at the tail.
     111                 :            :          */
     112                 :            :         struct list_head            images;
     113                 :            : 
     114                 :            :         int                         parent_devnum;
     115                 :            :         char                       *secondary_name;
     116                 :            :         td_image_t                 *secondary;
     117                 :            :         uint8_t                     secondary_mode;
     118                 :            : 
     119                 :            :         int                         FIXME_enospc_redirect_count_enabled;
     120                 :            :         uint64_t                    FIXME_enospc_redirect_count;
     121                 :            : 
     122                 :            :         /*
     123                 :            :          * when we encounter ENOSPC on the primary leaf image in mirror mode, 
     124                 :            :          * we need to remove it from the VBD chain so that writes start going 
     125                 :            :          * on the secondary leaf. However, we cannot free the image at that 
     126                 :            :          * time since it might still have in-flight treqs referencing it.  
     127                 :            :          * Therefore, we move it into 'retired' until shutdown.
     128                 :            :          */
     129                 :            :         td_image_t                 *retired;
     130                 :            : 
     131                 :            :         int                         nbd_mirror_failed;
     132                 :            : 
     133                 :            :         struct list_head            new_requests;
     134                 :            :         struct list_head            pending_requests;
     135                 :            :         struct list_head            failed_requests;
     136                 :            :         struct list_head            completed_requests;
     137                 :            : 
     138                 :            :         td_vbd_request_t            request_list[MAX_REQUESTS]; /* XXX */
     139                 :            : 
     140                 :            :         struct list_head            next;
     141                 :            : 
     142                 :            :         uint16_t                    req_timeout; /* in seconds */
     143                 :            :         struct timeval              ts;
     144                 :            : 
     145                 :            :         uint64_t                    received;
     146                 :            :         uint64_t                    returned;
     147                 :            :         uint64_t                    kicked;
     148                 :            :         uint64_t                    secs_pending;
     149                 :            :         uint64_t                    retries;
     150                 :            :         uint64_t                    errors;
     151                 :            :         td_sector_count_t           secs;
     152                 :            : 
     153                 :            :         struct td_nbdserver        *nbdserver;
     154                 :            :         struct td_nbdserver        *nbdserver_new;
     155                 :            : 
     156                 :            :         /**
     157                 :            :          * We keep a copy of the disk info because we might receive a disk info
     158                 :            :          * request while we're in the paused state.
     159                 :            :          */
     160                 :            :         td_disk_info_t              disk_info;
     161                 :            : 
     162                 :            :         struct td_vbd_rrd           rrd;
     163                 :            :         stats_t vdi_stats;
     164                 :            : 
     165                 :            :         char                       *logpath;
     166                 :            : 
     167                 :            :         struct td_vbd_encryption   encryption;
     168                 :            : 
     169                 :            :         bool                       watchdog_warned;
     170                 :            : };
     171                 :            : 
     172                 :            : #define tapdisk_vbd_for_each_request(vreq, tmp, list)                   \
     173                 :            :         list_for_each_entry_safe((vreq), (tmp), (list), next)
     174                 :            : 
     175                 :            : #define tapdisk_vbd_for_each_image(vbd, image, tmp)     \
     176                 :            :         tapdisk_for_each_image_safe(image, tmp, &vbd->images)
     177                 :            : 
     178                 :            : #define tapdisk_vbd_for_each_blkif(vbd, blkif, tmp)     \
     179                 :            :         list_for_each_entry_safe((blkif), (tmp), (&vbd->rings), entry)
     180                 :            : 
     181                 :            : static inline void
     182                 :            : tapdisk_vbd_move_request(td_vbd_request_t *vreq, struct list_head *dest)
     183                 :            : {
     184                 :          1 :         list_del(&vreq->next);
     185                 :          1 :         INIT_LIST_HEAD(&vreq->next);
     186                 :          1 :         list_add_tail(&vreq->next, dest);
     187                 :          0 :         vreq->list_head = dest;
     188                 :            : }
     189                 :            : 
     190                 :            : td_vbd_t *tapdisk_vbd_create(td_uuid_t);
     191                 :            : int tapdisk_vbd_initialize(int, int, td_uuid_t);
     192                 :            : int tapdisk_vbd_open(td_vbd_t *, const char *, int, const char *, td_flag_t);
     193                 :            : int tapdisk_vbd_close(td_vbd_t *);
     194                 :            : 
     195                 :            : /**
     196                 :            :  * Opens a VDI.
     197                 :            :  *
     198                 :            :  * @params vbd output parameter that receives a handle to the opened VDI
     199                 :            :  * @param params type:/path/to/file
     200                 :            :  * @params flags TD_OPEN_* TODO which TD_OPEN_* flags are honored? How does
     201                 :            :  * each flag affect the behavior of this functions? Move TD_OPEN_* flag
     202                 :            :  * definitions close to this function (check if they're used only by this
     203                 :            :  * function)?
     204                 :            :  * @param prt_devnum parent minor (optional)
     205                 :            :  * @returns 0 on success
     206                 :            :  */
     207                 :            : int tapdisk_vbd_open_vdi(td_vbd_t * vbd, const char *params, td_flag_t flags,
     208                 :            :         int prt_devnum);
     209                 :            : void tapdisk_vbd_close_vdi(td_vbd_t *);
     210                 :            : 
     211                 :            : int tapdisk_vbd_attach(td_vbd_t *, const char *, int);
     212                 :            : void tapdisk_vbd_detach(td_vbd_t *);
     213                 :            : 
     214                 :            : int tapdisk_vbd_queue_request(td_vbd_t *, td_vbd_request_t *);
     215                 :            : void tapdisk_vbd_forward_request(td_request_t);
     216                 :            : 
     217                 :            : int tapdisk_vbd_get_disk_info(td_vbd_t *, td_disk_info_t *);
     218                 :            : int tapdisk_vbd_retry_needed(td_vbd_t *);
     219                 :            : int tapdisk_vbd_quiesce_queue(td_vbd_t *);
     220                 :            : int tapdisk_vbd_start_queue(td_vbd_t *);
     221                 :            : int tapdisk_vbd_issue_requests(td_vbd_t *);
     222                 :            : int tapdisk_vbd_kill_queue(td_vbd_t *);
     223                 :            : int tapdisk_vbd_pause(td_vbd_t *);
     224                 :            : void tapdisk_vbd_squash_pause_logging(bool squash);
     225                 :            : int tapdisk_vbd_resume(td_vbd_t *, const char *);
     226                 :            : void tapdisk_vbd_kick(td_vbd_t *);
     227                 :            : void tapdisk_vbd_check_state(td_vbd_t *);
     228                 :            : void tapdisk_vbd_free(td_vbd_t *);
     229                 :            : 
     230                 :            : void tapdisk_vbd_complete_td_request(td_request_t, int);
     231                 :            : int add_extent(tapdisk_extents_t *, td_request_t *);
     232                 :            : int tapdisk_vbd_issue_request(td_vbd_t *, td_vbd_request_t *);
     233                 :            : 
     234                 :            : /**
     235                 :            :  * Checks whether there are new requests and if so it submits them, prodived
     236                 :            :  * that the queue has not been quiesced.
     237                 :            :  *
     238                 :            :  * Returns 1 if new requests have been issued, otherwise it returns 0.
     239                 :            :  */
     240                 :            : int tapdisk_vbd_recheck_state(td_vbd_t *);
     241                 :            : 
     242                 :            : void tapdisk_vbd_check_progress(td_vbd_t *);
     243                 :            : void tapdisk_vbd_debug(td_vbd_t *);
     244                 :            : int tapdisk_vbd_start_nbdservers(td_vbd_t *);
     245                 :            : void tapdisk_vbd_stats(td_vbd_t *, td_stats_t *);
     246                 :            : void tapdisk_vbd_complete_block_status_request(td_request_t, int);
     247                 :            : 
     248                 :            : /**
     249                 :            :  * Tells whether the VBD contains at least one dead ring.
     250                 :            :  */
     251                 :            : bool tapdisk_vbd_contains_dead_rings(td_vbd_t * vbd);
     252                 :            : #endif

Generated by: LCOV version 1.13