Follow us on Google+ Follow us on Facebook Follow us on Twitter

Changeset mainline,2695


Ignore:
Timestamp:
2017-07-14T21:31:44Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
branch-nick:
main-clone
revision id:
jiri@wiwaxia-20170714213144-8o9eld0rjy87ukua
Message:

VBD needs to empty a newly created partition before exposing it to the volume server.

Location:
mainline/uspace
Files:
3 added
8 edited
1 moved

Legend:

Unmodified
Added
Removed
  • mainline/uspace/lib/label/Makefile

    r2675 r2695  
    3434SOURCES = \
    3535        src/dummy.c \
     36        src/empty.c \
    3637        src/mbr.c \
    3738        src/gpt.c \
  • mainline/uspace/lib/label/src/label.c

    r2674 r2695  
    3636#include <adt/list.h>
    3737#include <errno.h>
    38 #include <label.h>
     38#include <label/label.h>
    3939#include <mem.h>
    4040#include <stdlib.h>
  • mainline/uspace/lib/label/test/label.c

    r2675 r2695  
    2727 */
    2828
    29 #include <label.h>
     29#include <label/label.h>
    3030#include <mem.h>
    3131#include <pcut/pcut.h>
  • mainline/uspace/srv/bd/vbd/disk.c

    r2674 r2695  
    3939#include <errno.h>
    4040#include <io/log.h>
     41#include <label/empty.h>
     42#include <label/label.h>
    4143#include <loc.h>
    4244#include <stdio.h>
     
    842844        if (rc != EOK) {
    843845                log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating partition.");
     846                goto error;
     847        }
     848
     849        rc = label_part_empty(lpart);
     850        if (rc != EOK) {
     851                log_msg(LOG_DEFAULT, LVL_ERROR, "Error emptying partition.");
    844852                goto error;
    845853        }
  • mainline/uspace/srv/bd/vbd/types/vbd.h

    r2619 r2695  
    4141#include <atomic.h>
    4242#include <bd_srv.h>
    43 #include <label.h>
     43#include <label/label.h>
    4444#include <loc.h>
    4545#include <stdbool.h>
  • mainline/uspace/srv/bd/vbd/vbd.c

    r2447 r2695  
    3939#include <ipc/services.h>
    4040#include <ipc/vbd.h>
     41#include <label/label.h>
    4142#include <loc.h>
    4243#include <macros.h>
  • mainline/uspace/srv/volsrv/Makefile

    r2.1.32 r2695  
    2929USPACE_PREFIX = ../..
    3030
    31 LIBS = $(LIBBLOCK_PREFIX)/libblock.a
    32 EXTRA_CFLAGS = -I $(LIBBLOCK_PREFIX)
     31LIBS = \
     32        $(LIBLABEL_PREFIX)/liblabel.a \
     33        $(LIBBLOCK_PREFIX)/libblock.a
     34
     35EXTRA_CFLAGS = \
     36        -I$(LIBLABEL_PREFIX)/include \
     37        -I$(LIBBLOCK_PREFIX)
    3338
    3439BINARY = volsrv
  • mainline/uspace/srv/volsrv/empty.c

    r2404 r2695  
    3838#include <errno.h>
    3939#include <io/log.h>
     40#include <label/empty.h>
    4041#include <loc.h>
    4142#include <stdlib.h>
     
    4344#include "empty.h"
    4445
    45 /*
    46  * The partition will be considered empty if at least a minimum number of
    47  * bytes *and* blocks (whichever is larger) at the beginning and end of
    48  * the partition is zero.
    49  */
    50 enum {
    51         min_empty_bytes = 16384,
    52         /*
    53          * First block in ISO 9660 that cannot be empty is the first
    54          * volume descriptor at LBA 16
    55          */
    56         min_empty_blocks = 17
     46static int empty_get_bsize(void *, size_t *);
     47static int empty_get_nblocks(void *, aoff64_t *);
     48static int empty_read(void *, aoff64_t, size_t, void *);
     49static int empty_write(void *, aoff64_t, size_t, const void *);
     50
     51/** Provide disk access to liblabel */
     52static label_bd_ops_t empty_bd_ops = {
     53        .get_bsize = empty_get_bsize,
     54        .get_nblocks = empty_get_nblocks,
     55        .read = empty_read,
     56        .write = empty_write
    5757};
    58 
    59 static bool mem_is_zero(void *buf, size_t size)
    60 {
    61         uint8_t *bp;
    62         size_t i;
    63 
    64         bp = (uint8_t *)buf;
    65         for (i = 0; i < size; i++) {
    66                 if (bp[i] != 0)
    67                         return false;
    68         }
    69 
    70         return true;
    71 }
    72 
    73 /** Calculate number of blocks to check.
    74  *
    75  * Will store to @a *ncb the number of blocks that should be checked
    76  * at the beginning and end of device each.
    77  *
    78  * @param nblocks Total number of blocks on block device
    79  * @param block_size Block size
    80  * @param ncb Place to store number of blocks to check.
    81  */
    82 static void calc_num_check_blocks(aoff64_t nblocks, size_t block_size,
    83     aoff64_t *ncb)
    84 {
    85         aoff64_t n;
    86 
    87         /* Check first 16 kiB / 16 blocks, whichever is more */
    88         n = (min_empty_bytes + block_size - 1) / block_size;
    89         if (n < min_empty_blocks)
    90                 n = min_empty_blocks;
    91         /*
    92          * Limit to half of the device so we do not process the same blocks
    93          * twice
    94          */
    95         if (n > (nblocks + 1) / 2)
    96                 n = (nblocks + 1) / 2;
    97 
    98         *ncb = n;
    99 }
    10058
    10159int volsrv_part_is_empty(service_id_t sid, bool *rempty)
    10260{
    10361        int rc;
    104         bool block_inited = false;
    105         void *buf = NULL;
    106         aoff64_t nblocks;
    107         aoff64_t n;
    108         aoff64_t i;
    109         size_t block_size;
    110         bool empty;
     62        label_bd_t lbd;
    11163
    11264        rc = block_init(sid, 2048);
     
    11466                log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
    11567                    "block device service %zu", sid);
    116                 rc = EIO;
    117                 goto error;
     68                return EIO;
    11869        }
    11970
    120         block_inited = true;
     71        lbd.ops = &empty_bd_ops;
     72        lbd.arg = (void *)&sid;
    12173
    122         rc = block_get_bsize(sid, &block_size);
    123         if (rc != EOK) {
    124                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
    125                     "block size.");
    126                 rc = EIO;
    127                 goto error;
    128         }
     74        rc = label_bd_is_empty(&lbd, rempty);
    12975
    130         rc = block_get_nblocks(sid, &nblocks);
    131         if (rc != EOK) {
    132                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
    133                     "number of blocks.");
    134                 rc = EIO;
    135                 goto error;
    136         }
    137 
    138         calc_num_check_blocks(nblocks, block_size, &n);
    139 
    140         buf = calloc(block_size, 1);
    141         if (buf == NULL) {
    142                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
    143                 rc = ENOMEM;
    144                 goto error;
    145         }
    146 
    147         empty = true;
    148 
    149         for (i = 0; i < n; i++) {
    150                 rc = block_read_direct(sid, i, 1, buf);
    151                 if (rc != EOK) {
    152                         log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
    153                             "reading blocks.");
    154                         rc = EIO;
    155                         goto error;
    156                 }
    157 
    158                 if (!mem_is_zero(buf, block_size)) {
    159                         empty = false;
    160                         goto done;
    161                 }
    162         }
    163 
    164         for (i = 0; i < n; i++) {
    165                 rc = block_read_direct(sid, nblocks - n + i, 1, buf);
    166                 if (rc != EOK) {
    167                         log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
    168                             "reading blocks.");
    169                         rc = EIO;
    170                         goto error;
    171                 }
    172 
    173                 if (!mem_is_zero(buf, block_size)) {
    174                         empty = false;
    175                         goto done;
    176                 }
    177         }
    178 
    179 done:
    18076        block_fini(sid);
    181         free(buf);
    182         *rempty = empty;
    183         return EOK;
    184 error:
    185         if (block_inited)
    186                 block_fini(sid);
    187         if (buf != NULL)
    188                 free(buf);
    18977        return rc;
    19078}
     
    19381{
    19482        int rc;
    195         bool block_inited = false;
    196         void *buf = NULL;
    197         aoff64_t nblocks;
    198         aoff64_t n;
    199         aoff64_t i;
    200         size_t block_size;
     83        label_bd_t lbd;
    20184
    20285        rc = block_init(sid, 2048);
     
    20487                log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
    20588                    "block device service %zu", sid);
    206                 rc = EIO;
    207                 goto error;
     89                return EIO;
    20890        }
    20991
    210         block_inited = true;
     92        lbd.ops = &empty_bd_ops;
     93        lbd.arg = (void *)&sid;
    21194
    212         rc = block_get_bsize(sid, &block_size);
    213         if (rc != EOK) {
    214                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
    215                     "block size.");
    216                 rc = EIO;
    217                 goto error;
    218         }
    219 
    220         rc = block_get_nblocks(sid, &nblocks);
    221         if (rc != EOK) {
    222                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
    223                     "number of blocks.");
    224                 rc = EIO;
    225                 goto error;
    226         }
    227 
    228         calc_num_check_blocks(nblocks, block_size, &n);
    229 
    230         buf = calloc(block_size, 1);
    231         if (buf == NULL) {
    232                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
    233                 rc = ENOMEM;
    234                 goto error;
    235         }
    236 
    237         for (i = 0; i < n; i++) {
    238                 rc = block_write_direct(sid, i, 1, buf);
    239                 if (rc != EOK) {
    240                         log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
    241                             "reading blocks.");
    242                         rc = EIO;
    243                         goto error;
    244                 }
    245         }
    246 
    247         for (i = 0; i < n; i++) {
    248                 rc = block_write_direct(sid, nblocks - n + i, 1, buf);
    249                 if (rc != EOK) {
    250                         log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
    251                             "reading blocks.");
    252                         rc = EIO;
    253                         goto error;
    254                 }
    255         }
     95        rc = label_bd_empty(&lbd);
    25696
    25797        block_fini(sid);
    258         free(buf);
    259         return EOK;
    260 error:
    261         if (block_inited)
    262                 block_fini(sid);
    263         if (buf != NULL)
    264                 free(buf);
    26598        return rc;
     99}
     100
     101/** Get block size wrapper for liblabel */
     102static int empty_get_bsize(void *arg, size_t *bsize)
     103{
     104        service_id_t svc_id = *(service_id_t *)arg;
     105        return block_get_bsize(svc_id, bsize);
     106}
     107
     108/** Get number of blocks wrapper for liblabel */
     109static int empty_get_nblocks(void *arg, aoff64_t *nblocks)
     110{
     111        service_id_t svc_id = *(service_id_t *)arg;
     112        return block_get_nblocks(svc_id, nblocks);
     113}
     114
     115/** Read blocks wrapper for liblabel */
     116static int empty_read(void *arg, aoff64_t ba, size_t cnt, void *buf)
     117{
     118        service_id_t svc_id = *(service_id_t *)arg;
     119        return block_read_direct(svc_id, ba, cnt, buf);
     120}
     121
     122/** Write blocks wrapper for liblabel */
     123static int empty_write(void *arg, aoff64_t ba, size_t cnt, const void *data)
     124{
     125        service_id_t svc_id = *(service_id_t *)arg;
     126        return block_write_direct(svc_id, ba, cnt, data);
    266127}
    267128
Note: See TracChangeset for help on using the changeset viewer.