LCOV - code coverage report
Current view: top level - drivers - tapdisk-vbd.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.3 % 6 5
Test Date: 2026-06-26 00:00:00 Functions: - 0 0
Branches: 50.0 % 8 4

             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-metrics.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_uuid_t                   uuid;
      86                 :             : 
      87                 :             :         /**
      88                 :             :          * shared rings
      89                 :             :          */
      90                 :             :         struct list_head           rings;
      91                 :             : 
      92                 :             :         /**
      93                 :             :          * List of rings that contain pending requests but a disconnection was
      94                 :             :          * issued. We need to maintain these rings until all their pending requests
      95                 :             :          * complete. When the last request completes, the ring is destroyed and
      96                 :             :          * removed from this list.
      97                 :             :          */
      98                 :             :         struct list_head            dead_rings;
      99                 :             : 
     100                 :             :         td_flag_t                   flags;
     101                 :             : 
     102                 :             :         /**
     103                 :             :          * VBD state (TD_VBD_XXX, excluding SECONDARY and request-related)
     104                 :             :          */
     105                 :             :         td_flag_t                   state;
     106                 :             : 
     107                 :             :         /**
     108                 :             :          * List of images: the leaf is at the head, the tree root is at the tail.
     109                 :             :          */
     110                 :             :         struct list_head            images;
     111                 :             : 
     112                 :             :         int                         parent_devnum;
     113                 :             :         char                       *secondary_name;
     114                 :             :         td_image_t                 *secondary;
     115                 :             :         uint8_t                     secondary_mode;
     116                 :             : 
     117                 :             :         int                         FIXME_enospc_redirect_count_enabled;
     118                 :             :         uint64_t                    FIXME_enospc_redirect_count;
     119                 :             : 
     120                 :             :         /*
     121                 :             :          * when we encounter ENOSPC on the primary leaf image in mirror mode, 
     122                 :             :          * we need to remove it from the VBD chain so that writes start going 
     123                 :             :          * on the secondary leaf. However, we cannot free the image at that 
     124                 :             :          * time since it might still have in-flight treqs referencing it.  
     125                 :             :          * Therefore, we move it into 'retired' until shutdown.
     126                 :             :          */
     127                 :             :         td_image_t                 *retired;
     128                 :             : 
     129                 :             :         int                         nbd_mirror_failed;
     130                 :             : 
     131                 :             :         struct list_head            new_requests;
     132                 :             :         struct list_head            pending_requests;
     133                 :             :         struct list_head            failed_requests;
     134                 :             :         struct list_head            completed_requests;
     135                 :             : 
     136                 :             :         td_vbd_request_t            request_list[MAX_REQUESTS]; /* XXX */
     137                 :             : 
     138                 :             :         struct list_head            next;
     139                 :             : 
     140                 :             :         uint16_t                    req_timeout; /* in seconds */
     141                 :             :         struct timeval              ts;
     142                 :             : 
     143                 :             :         uint64_t                    received;
     144                 :             :         uint64_t                    returned;
     145                 :             :         uint64_t                    kicked;
     146                 :             :         uint64_t                    secs_pending;
     147                 :             :         uint64_t                    retries;
     148                 :             :         uint64_t                    errors;
     149                 :             :         td_sector_count_t           secs;
     150                 :             : 
     151                 :             :         struct td_nbdserver        *nbdserver;
     152                 :             :         struct td_nbdserver        *nbdserver_new;
     153                 :             : 
     154                 :             :         /**
     155                 :             :          * We keep a copy of the disk info because we might receive a disk info
     156                 :             :          * request while we're in the paused state.
     157                 :             :          */
     158                 :             :         td_disk_info_t              disk_info;
     159                 :             : 
     160                 :             :         struct td_vbd_rrd           rrd;
     161                 :             :         stats_t vdi_stats;
     162                 :             : 
     163                 :             :         char                       *logpath;
     164                 :             : 
     165                 :             :         struct td_vbd_encryption   encryption;
     166                 :             : 
     167                 :             :         bool                       watchdog_warned;
     168                 :             : 
     169                 :             :         int                        lock_fd;
     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                 :           1 : 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         [ +  - ]:           1 :         vreq->list_head = dest;
     188                 :           0 : }
     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_lock(td_vbd_t *);
     212                 :             : void tapdisk_vbd_unlock(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 2.0-1