Changeset 603c1d1f in mainline


Ignore:
Timestamp:
2015-07-05T18:53:00Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bf7ddde
Parents:
99c23405
Message:

Persistent partition table creation and destruction.

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/fdisk/src/fdisk.c

    r99c23405 r603c1d1f  
    317317int fdisk_dev_open(fdisk_t *fdisk, service_id_t sid, fdisk_dev_t **rdev)
    318318{
     319        vol_disk_info_t vinfo;
    319320        fdisk_dev_t *dev = NULL;
    320321        service_id_t *psids = NULL;
     
    331332        list_initialize(&dev->parts_ba);
    332333
    333         printf("get info\n");
     334        rc = vol_disk_info(fdisk->vol, sid, &vinfo);
     335        if (rc != EOK) {
     336                rc = EIO;
     337                goto error;
     338        }
     339
     340        dev->dcnt = vinfo.dcnt;
     341
     342        if (dev->dcnt != dc_label)
     343                goto done;
     344
     345        printf("get label info\n");
    334346        rc = vbd_disk_info(fdisk->vbd, sid, &dev->dinfo);
    335347        if (rc != EOK) {
     
    361373
    362374        free(psids);
     375done:
    363376        *rdev = dev;
    364377        return EOK;
  • uspace/lib/label/include/std/gpt.h

    r99c23405 r603c1d1f  
    3838#include <sys/types.h>
    3939
    40 /** Block address of GPT header. */
    41 #define GPT_HDR_BA      1
     40enum {
     41        /** Block address of primary GPT header. */
     42        gpt_hdr_ba = 1,
     43
     44        /** Minimum size of partition table in bytes, required by std. */
     45        gpt_ptable_min_size = 16384,
     46
     47        /** GPT revision */
     48        gpt_revision = 0x00010000
     49};
    4250
    4351/** GPT header */
  • uspace/lib/label/include/types/liblabel.h

    r99c23405 r603c1d1f  
    111111
    112112typedef struct {
     113        uint64_t hdr_ba[2];
    113114        uint64_t ptable_ba[2];
    114115        size_t esize;
     
    125126        label_type_t ltype;
    126127        /** Block device service ID */
    127         service_id_t svcid;
     128        service_id_t svc_id;
    128129        /** Partitions */
    129130        list_t parts; /* of label_part_t */
  • uspace/lib/label/src/gpt.c

    r99c23405 r603c1d1f  
    120120        }
    121121
    122         rc = block_read_direct(sid, GPT_HDR_BA, 1, gpt_hdr[0]);
     122        rc = block_read_direct(sid, gpt_hdr_ba, 1, gpt_hdr[0]);
    123123        if (rc != EOK) {
    124124                rc = EIO;
     
    200200        label->ops = &gpt_label_ops;
    201201        label->ltype = lt_gpt;
    202         label->svcid = sid;
     202        label->svc_id = sid;
    203203        label->ablock0 = ba_min;
    204204        label->anblocks = ba_max - ba_min + 1;
     
    206206        label->block_size = bsize;
    207207
     208        label->lt.gpt.hdr_ba[0] = gpt_hdr_ba;
     209        label->lt.gpt.hdr_ba[1] = h1ba;
    208210        label->lt.gpt.ptable_ba[0] = ptba[0];
    209211        label->lt.gpt.ptable_ba[1] = ptba[1];
     
    222224static int gpt_create(service_id_t sid, label_t **rlabel)
    223225{
    224         return EOK;
     226        label_t *label = NULL;
     227        gpt_header_t *gpt_hdr = NULL;
     228        uint8_t *etable = NULL;
     229        size_t bsize;
     230        uint32_t num_entries;
     231        uint32_t esize;
     232        uint64_t ptba[2];
     233        uint64_t hdr_ba[2];
     234        uint64_t pt_blocks;
     235        uint64_t ba_min, ba_max;
     236        aoff64_t nblocks;
     237        uint64_t resv_blocks;
     238        int i, j;
     239        int rc;
     240
     241        rc = block_get_bsize(sid, &bsize);
     242        if (rc != EOK) {
     243                rc = EIO;
     244                goto error;
     245        }
     246
     247        if (bsize < 512 || (bsize % 512) != 0) {
     248                rc = EINVAL;
     249                goto error;
     250        }
     251
     252        rc = block_get_nblocks(sid, &nblocks);
     253        if (rc != EOK) {
     254                rc = EIO;
     255                goto error;
     256        }
     257
     258        /* Number of blocks of a partition table */
     259        pt_blocks = gpt_ptable_min_size / bsize;
     260        /* Minimum number of reserved (not allocatable) blocks */
     261        resv_blocks = 3 + 2 * pt_blocks;
     262
     263        if (nblocks <= resv_blocks) {
     264                rc = ENOSPC;
     265                goto error;
     266        }
     267
     268        hdr_ba[0] = gpt_hdr_ba;
     269        hdr_ba[1] = nblocks - 1;
     270        ptba[0] = 2;
     271        ptba[1] = nblocks - 1 - pt_blocks;
     272        ba_min = ptba[0] + pt_blocks;
     273        ba_max = ptba[1] - 1;
     274        esize = sizeof(gpt_entry_t);
     275
     276        num_entries = pt_blocks * bsize / sizeof(gpt_entry_t);
     277
     278        for (i = 0; i < 2; i++) {
     279                gpt_hdr = calloc(1, bsize);
     280                if (gpt_hdr == NULL) {
     281                        rc = ENOMEM;
     282                        goto error;
     283                }
     284
     285                for (j = 0; j < 8; ++j)
     286                        gpt_hdr->efi_signature[j] = efi_signature[j];
     287                gpt_hdr->revision = host2uint32_t_le(gpt_revision);
     288                gpt_hdr->header_size = host2uint32_t_le(sizeof(gpt_header_t));
     289                gpt_hdr->header_crc32 = 0; /* XXX */
     290                gpt_hdr->my_lba = host2uint64_t_le(hdr_ba[i]);
     291                gpt_hdr->alternate_lba = host2uint64_t_le(hdr_ba[1 - i]);
     292                gpt_hdr->first_usable_lba = host2uint64_t_le(ba_min);
     293                gpt_hdr->last_usable_lba = host2uint64_t_le(ba_max);
     294                //gpt_hdr->disk_guid
     295                gpt_hdr->entry_lba = host2uint64_t_le(ptba[i]);
     296                gpt_hdr->num_entries = host2uint32_t_le(num_entries);
     297                gpt_hdr->entry_size = host2uint32_t_le(esize);
     298                gpt_hdr->pe_array_crc32 = 0; /* XXXX */
     299
     300                rc = block_write_direct(sid, hdr_ba[i], 1, gpt_hdr);
     301                if (rc != EOK) {
     302                        rc = EIO;
     303                        goto error;
     304                }
     305
     306                free(gpt_hdr);
     307                gpt_hdr = NULL;
     308
     309                etable = calloc(num_entries, esize);
     310                if (etable == NULL) {
     311                        rc = ENOMEM;
     312                        goto error;
     313                }
     314
     315                rc = block_write_direct(sid, ptba[i], pt_blocks, etable);
     316                if (rc != EOK) {
     317                        rc = EIO;
     318                        goto error;
     319                }
     320
     321                free(etable);
     322                etable = 0;
     323        }
     324
     325        label = calloc(1, sizeof(label_t));
     326        if (label == NULL)
     327                return ENOMEM;
     328
     329        list_initialize(&label->parts);
     330
     331        label->ops = &gpt_label_ops;
     332        label->ltype = lt_gpt;
     333        label->svc_id = sid;
     334        label->ablock0 = ba_min;
     335        label->anblocks = ba_max - ba_min + 1;
     336        label->pri_entries = num_entries;
     337        label->block_size = bsize;
     338
     339        label->lt.gpt.hdr_ba[0] = hdr_ba[0];
     340        label->lt.gpt.hdr_ba[1] = hdr_ba[1];
     341        label->lt.gpt.ptable_ba[0] = ptba[0];
     342        label->lt.gpt.ptable_ba[1] = ptba[1];
     343        label->lt.gpt.esize = esize;
     344
     345        *rlabel = label;
     346        return EOK;
     347error:
     348        free(etable);
     349        free(gpt_hdr);
     350        free(label);
     351        return rc;
    225352}
    226353
    227354static void gpt_close(label_t *label)
    228355{
     356        label_part_t *part;
     357
     358        part = gpt_part_first(label);
     359        while (part != NULL) {
     360                list_remove(&part->llabel);
     361                free(part);
     362                part = gpt_part_first(label);
     363        }
     364
    229365        free(label);
    230366}
     
    232368static int gpt_destroy(label_t *label)
    233369{
    234         return EOK;
     370        gpt_header_t *gpt_hdr = NULL;
     371        uint8_t *etable = NULL;
     372        label_part_t *part;
     373        uint64_t pt_blocks;
     374        int i;
     375        int rc;
     376
     377        part = gpt_part_first(label);
     378        if (part != NULL) {
     379                rc = ENOTEMPTY;
     380                goto error;
     381        }
     382
     383        pt_blocks = label->pri_entries * label->lt.gpt.esize /
     384            label->block_size;
     385
     386        for (i = 0; i < 2; i++) {
     387                gpt_hdr = calloc(1, label->block_size);
     388                if (gpt_hdr == NULL) {
     389                        rc = ENOMEM;
     390                        goto error;
     391                }
     392
     393                rc = block_write_direct(label->svc_id, label->lt.gpt.hdr_ba[i],
     394                    1, gpt_hdr);
     395                if (rc != EOK) {
     396                        rc = EIO;
     397                        goto error;
     398                }
     399
     400                free(gpt_hdr);
     401                gpt_hdr = NULL;
     402
     403                etable = calloc(label->pri_entries, label->lt.gpt.esize);
     404                if (etable == NULL) {
     405                        rc = ENOMEM;
     406                        goto error;
     407                }
     408
     409                rc = block_write_direct(label->svc_id,
     410                    label->lt.gpt.ptable_ba[i], pt_blocks, etable);
     411                if (rc != EOK) {
     412                        rc = EIO;
     413                        goto error;
     414                }
     415
     416                free(etable);
     417                etable = 0;
     418        }
     419
     420        free(label);
     421        return EOK;
     422error:
     423        return rc;
    235424}
    236425
     
    426615                    pos / label->block_size;
    427616
    428                 rc = block_read_direct(label->svcid, ba, 1, buf);
     617                rc = block_read_direct(label->svc_id, ba, 1, buf);
    429618                if (rc != EOK) {
    430619                        rc = EIO;
     
    436625                *e = *pte;
    437626
    438                 rc = block_write_direct(label->svcid, ba, 1, buf);
     627                rc = block_write_direct(label->svc_id, ba, 1, buf);
    439628                if (rc != EOK) {
    440629                        rc = EIO;
  • uspace/lib/label/src/label.c

    r99c23405 r603c1d1f  
    4141
    4242#include "gpt.h"
     43#include "mbr.h"
    4344
    4445static label_ops_t *probe_list[] = {
    4546        &gpt_label_ops,
     47        &mbr_label_ops,
    4648        NULL
    4749};
     
    7274                break;
    7375        case lt_mbr:
    74                 ops = NULL;
     76                ops = &mbr_label_ops;
    7577                break;
    7678        }
  • uspace/lib/label/src/mbr.c

    r99c23405 r603c1d1f  
    142142        label->ops = &mbr_label_ops;
    143143        label->ltype = lt_mbr;
     144        label->svc_id = sid;
     145        label->block_size = bsize;
    144146        label->ablock0 = mbr_ablock0;
    145147        label->anblocks = nblocks - mbr_ablock0;
     
    155157static int mbr_create(service_id_t sid, label_t **rlabel)
    156158{
    157         return EOK;
     159        label_t *label = NULL;
     160        mbr_br_block_t *mbr = NULL;
     161        aoff64_t nblocks;
     162        size_t bsize;
     163        int i;
     164        int rc;
     165
     166        rc = block_get_bsize(sid, &bsize);
     167        if (rc != EOK) {
     168                rc = EIO;
     169                goto error;
     170        }
     171
     172        rc = block_get_nblocks(sid, &nblocks);
     173        if (rc != EOK) {
     174                rc = EIO;
     175                goto error;
     176        }
     177
     178        mbr = calloc(1, bsize);
     179        if (mbr == NULL) {
     180                rc = ENOMEM;
     181                goto error;
     182        }
     183
     184        label = calloc(1, sizeof(label_t));
     185        if (label == NULL)
     186                return ENOMEM;
     187
     188        list_initialize(&label->parts);
     189
     190        mbr->media_id = 0;
     191        mbr->pad0 = 0;
     192        for (i = 0; i < mbr_nprimary; i++)
     193                mbr_unused_pte(&mbr->pte[i]);
     194        mbr->signature = host2uint16_t_le(mbr_br_signature);
     195
     196        rc = block_write_direct(sid, mbr_ba, 1, mbr);
     197        if (rc != EOK) {
     198                rc = EIO;
     199                goto error;
     200        }
     201
     202        free(mbr);
     203        mbr = NULL;
     204
     205        label->ops = &mbr_label_ops;
     206        label->ltype = lt_mbr;
     207        label->block_size = bsize;
     208        label->svc_id = sid;
     209        label->ablock0 = mbr_ablock0;
     210        label->anblocks = nblocks - mbr_ablock0;
     211        label->pri_entries = mbr_nprimary;
     212
     213        *rlabel = label;
     214        return EOK;
     215error:
     216        free(mbr);
     217        free(label);
     218        return rc;
    158219}
    159220
    160221static void mbr_close(label_t *label)
    161222{
     223        label_part_t *part;
     224
     225        part = mbr_part_first(label);
     226        while (part != NULL) {
     227                list_remove(&part->llabel);
     228                free(part);
     229
     230                part = mbr_part_first(label);
     231        }
     232
    162233        free(label);
    163234}
     
    165236static int mbr_destroy(label_t *label)
    166237{
    167         return EOK;
     238        mbr_br_block_t *mbr = NULL;
     239        label_part_t *part;
     240        int rc;
     241
     242        part = mbr_part_first(label);
     243        if (part != NULL) {
     244                rc = ENOTEMPTY;
     245                goto error;
     246        }
     247
     248        mbr = calloc(1, label->block_size);
     249        if (mbr == NULL) {
     250                rc = ENOMEM;
     251                goto error;
     252        }
     253
     254        rc = block_write_direct(label->svc_id, mbr_ba, 1, mbr);
     255        if (rc != EOK) {
     256                rc = EIO;
     257                goto error;
     258        }
     259
     260        free(mbr);
     261        mbr = NULL;
     262
     263        free(label);
     264        return EOK;
     265error:
     266        free(mbr);
     267        return rc;
    168268}
    169269
     
    340440                return ENOMEM;
    341441
    342         rc = block_read_direct(label->svcid, mbr_ba, 1, br);
     442        rc = block_read_direct(label->svc_id, mbr_ba, 1, br);
    343443        if (rc != EOK) {
    344444                rc = EIO;
     
    348448        br->pte[index] = *pte;
    349449
    350         rc = block_write_direct(label->svcid, mbr_ba, 1, br);
     450        rc = block_write_direct(label->svc_id, mbr_ba, 1, br);
    351451        if (rc != EOK) {
    352452                rc = EIO;
  • uspace/srv/bd/part/guid_part/guid_part.c

    r99c23405 r603c1d1f  
    250250        }
    251251
    252         rc = block_read_direct(indev_sid, GPT_HDR_BA, 1, gpt_hdr);
     252        rc = block_read_direct(indev_sid, gpt_hdr_ba, 1, gpt_hdr);
    253253        if (rc != EOK) {
    254254                printf(NAME ": Failed reading GPT header block.\n");
  • uspace/srv/bd/vbd/disk.c

    r99c23405 r603c1d1f  
    223223        }
    224224
     225        log_msg(LOG_DEFAULT, LVL_NOTE, "block_init(%zu)", sid);
    225226        rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
    226227        if (rc != EOK) {
     
    272273error:
    273274        label_close(label);
    274         if (block_inited)
     275        if (block_inited) {
     276                log_msg(LOG_DEFAULT, LVL_NOTE, "block_fini(%zu)", sid);
    275277                block_fini(sid);
     278        }
    276279        if (disk != NULL)
    277280                free(disk->svc_name);
     
    293296        list_remove(&disk->ldisks);
    294297        label_close(disk->label);
     298        log_msg(LOG_DEFAULT, LVL_NOTE, "block_fini(%zu)", sid);
     299        block_fini(sid);
    295300        free(disk);
    296301        return EOK;
     
    353358        label_t *label;
    354359        vbds_disk_t *disk;
     360        bool block_inited = false;
     361        size_t block_size;
    355362        int rc;
    356363
    357364        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create(%zu)", sid);
     365
     366        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create(%zu) - chkdup", sid);
    358367
    359368        /* Check for duplicates */
     
    362371                return EEXISTS;
    363372
     373        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create(%zu) - alloc", sid);
     374
    364375        disk = calloc(1, sizeof(vbds_disk_t));
    365376        if (disk == NULL)
    366377                return ENOMEM;
    367378
     379        rc = loc_service_get_name(sid, &disk->svc_name);
     380        if (rc != EOK) {
     381                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting disk service name.");
     382                rc = EIO;
     383                goto error;
     384        }
     385
     386        log_msg(LOG_DEFAULT, LVL_NOTE, "block_init(%zu)", sid);
     387        rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
     388        if (rc != EOK) {
     389                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening block device %s.",
     390                    disk->svc_name);
     391                rc = EIO;
     392                goto error;
     393        }
     394
     395        rc = block_get_bsize(sid, &block_size);
     396        if (rc != EOK) {
     397                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting block size of %s.",
     398                    disk->svc_name);
     399                rc = EIO;
     400                goto error;
     401        }
     402
     403        block_inited = true;
     404
     405        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create(%zu) - label_create", sid);
     406
    368407        rc = label_create(sid, ltype, &label);
    369408        if (rc != EOK)
     
    372411        disk->svc_id = sid;
    373412        disk->label = label;
     413        disk->block_size = block_size;
     414        list_initialize(&disk->parts);
     415
    374416        list_append(&disk->ldisks, &vbds_disks);
     417
     418        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create(%zu) - success", sid);
    375419        return EOK;
    376420error:
     421        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create(%zu) - failure", sid);
     422        if (block_inited) {
     423                log_msg(LOG_DEFAULT, LVL_NOTE, "block_fini(%zu)", sid);
     424                block_fini(sid);
     425        }
     426        if (disk != NULL)
     427                free(disk->svc_name);
    377428        free(disk);
    378429        return rc;
     
    397448
    398449        list_remove(&disk->ldisks);
     450        log_msg(LOG_DEFAULT, LVL_NOTE, "block_fini(%zu)", sid);
     451        block_fini(sid);
    399452        free(disk);
    400453        return EOK;
  • uspace/srv/volsrv/disk.c

    r99c23405 r603c1d1f  
    257257}
    258258
     259int vol_disk_label_create(vol_disk_t *disk, label_type_t ltype)
     260{
     261        int rc;
     262
     263        rc = vbd_label_create(vbd, disk->svc_id, ltype);
     264        if (rc != EOK)
     265                return rc;
     266
     267        disk->dcnt = dc_label;
     268        disk->ltype = ltype;
     269
     270        return EOK;
     271}
     272
     273int vol_disk_empty(vol_disk_t *disk)
     274{
     275        int rc;
     276
     277        if (disk->dcnt == dc_label) {
     278                rc = vbd_label_delete(vbd, disk->svc_id);
     279                if (rc != EOK)
     280                        return rc;
     281        }
     282
     283        disk->dcnt = dc_empty;
     284
     285        return EOK;
     286}
     287
     288
    259289/** @}
    260290 */
  • uspace/srv/volsrv/disk.h

    r99c23405 r603c1d1f  
    4545extern int vol_disk_get_ids(service_id_t *, size_t, size_t *);
    4646extern int vol_disk_find_by_id(service_id_t, vol_disk_t **);
     47extern int vol_disk_label_create(vol_disk_t *, label_type_t);
     48extern int vol_disk_empty(vol_disk_t *);
    4749
    4850#endif
  • uspace/srv/volsrv/volsrv.c

    r99c23405 r603c1d1f  
    146146        }
    147147
    148         disk->dcnt = dc_label;
    149         disk->ltype = ltype;
     148        rc = vol_disk_label_create(disk, ltype);
     149        if (rc != EOK) {
     150                async_answer_0(iid, EIO);
     151                return;
     152        }
    150153
    151154        async_answer_0(iid, EOK);
     
    166169        }
    167170
    168         disk->dcnt = dc_empty;
     171        rc = vol_disk_empty(disk);
     172        if (rc != EOK) {
     173                async_answer_0(iid, EIO);
     174                return;
     175        }
    169176
    170177        async_answer_0(iid, EOK);
Note: See TracChangeset for help on using the changeset viewer.