]> git.ipfire.org Git - thirdparty/util-linux.git/blame - fdisks/utils.c
libfdisk: add fdisk_reset_alignment()
[thirdparty/util-linux.git] / fdisks / utils.c
CommitLineData
823f0fd1
DB
1/*
2 * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <errno.h>
20#include <string.h>
21#include <stdlib.h>
22#include <unistd.h>
559d921e 23#include <ctype.h>
e53ced85
DB
24#ifdef HAVE_LIBBLKID
25#include <blkid.h>
26#endif
823f0fd1 27
e53ced85
DB
28#include "nls.h"
29#include "blkdev.h"
823f0fd1
DB
30#include "common.h"
31#include "fdisk.h"
32
a71601af
KZ
33#include "fdiskdoslabel.h"
34#include "fdisksunlabel.h"
35
f7b1f75e
DB
36int fdisk_debug_mask;
37
b8855c86 38/*
4477d73f 39 * Label probing functions.
b8855c86
DB
40 */
41static const struct fdisk_label *labels[] =
42{
766d5156 43 &gpt_label,
b8855c86 44 &dos_label,
b8855c86 45 &sun_label,
79c8a145 46 &sgi_label,
b8855c86 47 &aix_label,
79c8a145 48 &bsd_label,
b8855c86
DB
49 &mac_label,
50};
51
61c4cb85 52
b8855c86
DB
53static int __probe_labels(struct fdisk_context *cxt)
54{
48f2fdbf 55 size_t i;
b8855c86 56
ff5775bd 57 cxt->disklabel = FDISK_DISKLABEL_ANY;
b8855c86
DB
58
59 for (i = 0; i < ARRAY_SIZE(labels); i++) {
441afd48 60 if (!labels[i]->probe || labels[i]->probe(cxt) != 1)
79c8a145
DB
61 continue;
62
63 cxt->label = labels[i];
64
61c4cb85 65 DBG(LABEL, dbgprint("detected a %s label", cxt->label->name));
79c8a145 66 return 0;
b8855c86
DB
67 }
68
79c8a145 69 return 1; /* not found */
b8855c86
DB
70}
71
a71601af 72/**
639f1d56 73 * fdisk_create_disklabel:
a71601af 74 * @cxt: fdisk context
639f1d56 75 * @name: label name
a71601af 76 *
639f1d56
DB
77 * Creates a new disk label of type @name. If @name is NULL, then it
78 * will create a default system label type, either SUN or DOS.
a71601af 79 *
639f1d56 80 * Returns 0 on success, otherwise, a corresponding error.
a71601af 81 */
639f1d56 82int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name)
a71601af
KZ
83{
84 if (!cxt)
85 return -EINVAL;
ed21ffd3 86
639f1d56 87 cxt->label = NULL;
ed21ffd3 88
639f1d56
DB
89 if (!name) { /* use default label creation */
90#ifdef __sparc__
91 cxt->label = &sun_label;
a71601af 92#else
639f1d56 93 cxt->label = &dos_label;
a71601af 94#endif
639f1d56
DB
95 } else {
96 size_t i;
97
98 for (i = 0; i < ARRAY_SIZE(labels); i++) {
99 if (strcmp(name, labels[i]->name) != 0)
100 continue;
101
102 cxt->label = labels[i];
103 DBG(LABEL, dbgprint("changing to %s label\n", cxt->label->name));
104 break;
105 }
106 }
107
108 if (!cxt->label)
109 return -EINVAL;
441afd48
KZ
110 if (!cxt->label->create)
111 return -ENOSYS;
639f1d56 112
cf3808e4
KZ
113 fdisk_reset_alignment(cxt);
114
639f1d56 115 return cxt->label->create(cxt);
a71601af
KZ
116}
117
823f0fd1
DB
118/**
119 * fdisk_new_context:
537187be 120 * @fname: path to the device to be handled
25b529fe
DB
121 * @readonly: how to open the device
122 *
123 * If the @readonly flag is set to false, fdisk will attempt to open
124 * the device with read-write mode and will fallback to read-only if
125 * unsuccessful.
823f0fd1 126 *
537187be 127 * Returns: newly allocated fdisk context or NULL upon failure.
823f0fd1 128 */
7657d3e2 129struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly)
823f0fd1
DB
130{
131 int fd, errsv = 0;
132 struct fdisk_context *cxt = NULL;
133
95f9f309
KZ
134 DBG(CONTEXT, dbgprint("initializing context for %s", fname));
135
7657d3e2 136 if (readonly == 1 || (fd = open(fname, O_RDWR)) < 0) {
823f0fd1
DB
137 if ((fd = open(fname, O_RDONLY)) < 0)
138 return NULL;
7657d3e2 139 readonly = 1;
f7b1f75e 140 }
823f0fd1
DB
141
142 cxt = calloc(1, sizeof(*cxt));
143 if (!cxt)
144 goto fail;
145
146 cxt->dev_fd = fd;
147 cxt->dev_path = strdup(fname);
148 if (!cxt->dev_path)
149 goto fail;
618882d6 150
aa42788d
KZ
151 fdisk_discover_topology(cxt);
152 fdisk_discover_geometry(cxt);
823f0fd1 153
3eb78aa7
KZ
154 if (fdisk_read_firstsector(cxt) < 0)
155 goto fail;
156
9a5e29e9
KZ
157 /* detect labels and apply labes specific stuff (e.g geomery)
158 * to the context */
b8855c86
DB
159 __probe_labels(cxt);
160
cf3808e4 161 fdisk_reset_alignment(cxt);
9a5e29e9 162
2b1a43cf
KZ
163 DBG(CONTEXT, dbgprint("context %p initialized for %s [%s]",
164 cxt, fname,
165 readonly ? "READ-ONLY" : "READ-WRITE"));
823f0fd1
DB
166 return cxt;
167fail:
168 errsv = errno;
169 fdisk_free_context(cxt);
170 errno = errsv;
7657d3e2
KZ
171
172 DBG(CONTEXT, dbgprint("failed to initialize context for %s: %m", fname));
823f0fd1
DB
173 return NULL;
174}
175
176/**
177 * fdisk_free_context:
178 * @cxt: fdisk context
179 *
180 * Deallocates context struct.
181 */
182void fdisk_free_context(struct fdisk_context *cxt)
183{
184 if (!cxt)
185 return;
186
2b1a43cf 187 DBG(CONTEXT, dbgprint("freeing context %p for %s", cxt, cxt->dev_path));
823f0fd1
DB
188 close(cxt->dev_fd);
189 free(cxt->dev_path);
67987b47 190 free(cxt->firstsector);
823f0fd1
DB
191 free(cxt);
192}
559d921e 193
559d921e 194
2b1a43cf 195